994 lines
28 KiB
JavaScript
994 lines
28 KiB
JavaScript
var utils = require('./src/utils');
|
|
var crossCtl = require('./src/crossCtl');
|
|
|
|
var compression = require('compression');
|
|
var express = require('express');
|
|
// var cors = require('cors')
|
|
var path = require('path');
|
|
var morgan = require('morgan');
|
|
var rfs = require('rotating-file-stream'); // version 2.x
|
|
var favicon = require('serve-favicon');
|
|
var cookieParser = require('cookie-parser');
|
|
var bodyParser = require('body-parser');
|
|
|
|
var passport = require('passport');
|
|
var LocalStrategy = require('passport-local').Strategy;
|
|
var FacebookStrategy = require('passport-facebook').Strategy;
|
|
var GoogleStrategy = require('passport-google-oauth20').Strategy;
|
|
var KakaoStrategy = require('passport-kakao').Strategy;
|
|
var AppleStrategy = require('passport-apple');
|
|
var CustomStrategy = require('passport-custom').Strategy;
|
|
|
|
var mysql = require('mysql');
|
|
|
|
var moment = require('moment');
|
|
|
|
var app = express();
|
|
|
|
app.use(express.json({ limit: '50mb' }));
|
|
app.use(express.urlencoded({ limit: '50mb', extended: false }));
|
|
|
|
app.set('trust proxy', true);
|
|
|
|
var session = require('express-session');
|
|
var RedisStore = require('connect-redis')(session);
|
|
|
|
var sessionDomain = 'safekiso.com';
|
|
// // console.log('huk sessionDomain = ', sessionDomain)
|
|
|
|
var redisOptions = {};
|
|
if (crossCtl.sConfig.redis) {
|
|
redisOptions = {
|
|
...crossCtl.config.options.redis,
|
|
...crossCtl.sConfig.redis,
|
|
};
|
|
} else {
|
|
redisOptions = { ...crossCtl.config.options.redis };
|
|
}
|
|
// console.log('huk redisOptions = ', redisOptions)
|
|
|
|
var cookieOptions = {};
|
|
if (crossCtl.sConfig.cookie) {
|
|
cookieOptions = crossCtl.sConfig.cookie;
|
|
} else {
|
|
cookieOptions = {
|
|
path: '/',
|
|
// sameSite: 'strict',
|
|
// domain: sessionDomain, // !!!!!!!
|
|
// maxAge: 1000 * 60 * 60 * 24 // 24 hours
|
|
maxAge: 1000 * 60 * 60 * 1, // 1 hours
|
|
};
|
|
}
|
|
// console.log('huk cookieOptions = ', cookieOptions)
|
|
|
|
// redirect HTTP to HTTPS
|
|
app.all('*', (req, res, next) => {
|
|
let protocol = req.headers['x-forwarded-proto'] || req.protocol;
|
|
// console.log('protocol=', protocol)
|
|
if (protocol == 'https') {
|
|
next();
|
|
} else {
|
|
if (crossCtl.sConfig.forceHttps === true) {
|
|
let from = `${protocol}://${req.hostname}${req.url}`;
|
|
let to = `https://${req.hostname}${req.url}`;
|
|
// log and redirect
|
|
console.log(`[${req.method}]: ${from} -> ${to}`);
|
|
res.redirect(to);
|
|
} else {
|
|
next();
|
|
}
|
|
}
|
|
});
|
|
|
|
app.use(
|
|
session({
|
|
store: new RedisStore(redisOptions),
|
|
secret: 'in got we trust!!!',
|
|
resave: true,
|
|
saveUninitialized: true,
|
|
// ttl: 60 * 1,
|
|
rolling: true,
|
|
cookie: cookieOptions,
|
|
})
|
|
);
|
|
|
|
app.use(function (req, res, next) {
|
|
const cleanup = () => {
|
|
res.removeListener('finish', logStatsics);
|
|
res.removeListener('close', abortFn);
|
|
res.removeListener('error', errorFn);
|
|
};
|
|
|
|
const logStatsics = () => {
|
|
cleanup();
|
|
// console.log('logStatsics()')
|
|
// console.info(`${req.method} ${req.originalUrl}`)
|
|
// console.info(`${req.sessionID}`)
|
|
// crossCtl.redis.logHit(req.originalUrl)
|
|
if (req.sessionID) {
|
|
crossCtl.redis.logSession(req.sessionID);
|
|
} else {
|
|
// console.log('no session request!!!')
|
|
}
|
|
};
|
|
|
|
const abortFn = () => {
|
|
console.warn('Request aborted by the client');
|
|
cleanup();
|
|
};
|
|
|
|
const errorFn = (err) => {
|
|
console.error(`Request pipeline error: ${err}`);
|
|
cleanup();
|
|
};
|
|
|
|
res.on('finish', logStatsics); // successful pipeline (regardless of its response)
|
|
res.on('close', abortFn); // aborted pipeline
|
|
res.on('error', errorFn); // pipeline internal error
|
|
|
|
next();
|
|
});
|
|
|
|
app.use(compression());
|
|
// app.use(cors())
|
|
|
|
// view engine setup
|
|
app.set('view engine', 'ejs');
|
|
|
|
// var i18n = require('i18n')
|
|
|
|
crossCtl.i18n.configure({
|
|
locales: ['ko', 'en'],
|
|
defaultLocale: 'ko',
|
|
autoReload: true, // watch for changes in json files to reload locale on updates - defaults to false
|
|
updateFiles: true, // whether to write new locale information to disk - defaults to true
|
|
syncFiles: true, // sync locale information across all files - defaults to false
|
|
directory: path.join(__dirname, 'modules', crossCtl.sConfig.type, 'locales'),
|
|
});
|
|
|
|
// i18n.setLocale('ko');
|
|
|
|
app.use(crossCtl.i18n.init);
|
|
|
|
// uncomment after placing your favicon in /public
|
|
var morganOptions = {
|
|
skip: function (req, res) {
|
|
return req.url === '/ping';
|
|
},
|
|
};
|
|
// app.use(logger('dev', morganOptions))
|
|
// morgan
|
|
|
|
// create a rotating write stream
|
|
var accessLogStream = rfs.createStream(utils.generator, {
|
|
// interval: '1M', // rotate monthly
|
|
// interval: '1m', // rotate minitly
|
|
// immutable: true,
|
|
// rotate: 1,
|
|
// size: "30K",
|
|
interval: '1M', // rotate minitly
|
|
path: path.join(__dirname, crossCtl.sConfig.log),
|
|
});
|
|
|
|
accessLogStream.on('open', (filename) => {
|
|
// console.log('accessLogStream on open with ', filename)
|
|
});
|
|
|
|
accessLogStream.on('rotation', () => {
|
|
// console.log('accessLogStream on rotation')
|
|
});
|
|
|
|
accessLogStream.on('rotated', (filename) => {
|
|
// console.log('accessLogStream on rotated to ', filename)
|
|
});
|
|
|
|
accessLogStream.on('warning', (error) => {
|
|
// console.log('accessLogStream on warning with ', error )
|
|
});
|
|
|
|
accessLogStream.on('error', (error) => {
|
|
// console.log('accessLogStream on error with ', error )
|
|
});
|
|
|
|
// setup the logger
|
|
|
|
// morgan.token('trueIp', req => utils.getIPFromReq(req));
|
|
/*
|
|
morgan.token('remote-addr', function (req) {
|
|
return utils.getIPFromReq(req)
|
|
});
|
|
*/
|
|
|
|
app.use(morgan('combined', { stream: accessLogStream }));
|
|
|
|
app.use(bodyParser.json());
|
|
app.use(bodyParser.urlencoded({ extended: false }));
|
|
|
|
// app.use(bodyParser.json({limit: '10mb', extended: true}))
|
|
// app.use(bodyParser.urlencoded({limit: '10mb', extended: true}))
|
|
|
|
app.use(cookieParser());
|
|
|
|
app.set('views', [
|
|
path.join(__dirname, 'modules', 'base', 'views'),
|
|
path.join(__dirname, 'modules', crossCtl.sConfig.type, 'views'),
|
|
]);
|
|
|
|
// app.set("views", path.join(__dirname, "modules", "base", "views"));
|
|
// app.set("views",path.join(__dirname, "modules", crossCtl.sConfig.type, "views"));
|
|
|
|
/*
|
|
app.use(
|
|
favicon(
|
|
path.join(
|
|
__dirname,
|
|
'modules',
|
|
crossCtl.sConfig.type,
|
|
'wwwroot',
|
|
'favicon.ico'
|
|
)
|
|
)
|
|
);
|
|
*/
|
|
|
|
//
|
|
|
|
if (crossCtl.sConfig.clientDistInfo != undefined) {
|
|
app.use(
|
|
express.static(
|
|
path.join(
|
|
__dirname,
|
|
'modules',
|
|
crossCtl.sConfig.type,
|
|
'client',
|
|
// crossCtl.sConfig.clientDistInfo.fromPath,
|
|
'.output',
|
|
'public'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
app.use(
|
|
express.static(
|
|
path.join(__dirname, 'modules', crossCtl.sConfig.type, 'wwwroot')
|
|
)
|
|
);
|
|
app.use(express.static(path.join(__dirname, 'modules', 'base', 'wwwroot')));
|
|
app.use(
|
|
express.static(path.join(__dirname, 'modules', 'base', 'wwwroot', 'admindek'))
|
|
);
|
|
|
|
const fs = require('fs');
|
|
|
|
/*
|
|
if (crossCtl.sConfig.type === 'inspond') {
|
|
var wwwrootPath = path.join(__dirname, '..', 'wwwroot');
|
|
// console.log('wwwrootPath=', wwwrootPath)
|
|
if (fs.existsSync(wwwrootPath)) {
|
|
app.use(express.static(wwwrootPath));
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
crossCtl.text2png.generatePngFromText('졸리\n만세!', {}, 'modules/linkcare/wwwroot/out.png', (err) => {
|
|
console.log('after generatePngFromText(), err=', err)
|
|
})
|
|
*/
|
|
|
|
app.use(passport.initialize());
|
|
app.use(passport.session());
|
|
|
|
var passportOptions = crossCtl.sConfig.passport; // crossCtl.config.options.passport
|
|
|
|
function doAuth(type, key, token, info, cb) {
|
|
// var qry = 'SELECT * FROM ' + crossCtl.db.options.database + '.tbl_account_users WHERE auth_type = ' + type + ' AND auth_key = ' + mysql.escape(key) + ' AND status = 0'
|
|
var qry =
|
|
'SELECT * FROM ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users WHERE auth_type = ' +
|
|
type +
|
|
' AND auth_key = ' +
|
|
mysql.escape(key) +
|
|
' AND site_id = ' +
|
|
mysql.escape(crossCtl.sConfig.type);
|
|
|
|
if (crossCtl.sConfig.type == 'usm') {
|
|
var roleTag = info.roleTag ? info.roleTag : 'student';
|
|
qry =
|
|
'SELECT * FROM ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users WHERE auth_type = ' +
|
|
type +
|
|
' AND auth_key = ' +
|
|
mysql.escape(key) +
|
|
' AND site_id = ' +
|
|
mysql.escape(crossCtl.sConfig.type) +
|
|
' AND role_tag = ' +
|
|
mysql.escape(roleTag);
|
|
}
|
|
|
|
var prefDataJson = {};
|
|
var resultUser = {
|
|
auth_flag: false,
|
|
auth_type: type,
|
|
reason: 'undefined',
|
|
code: 0,
|
|
};
|
|
|
|
crossCtl.db.doEasyQuery(qry, function (err, results) {
|
|
if (err) {
|
|
cb(err, null);
|
|
} else {
|
|
if (results.length === 0) {
|
|
if (type === 0) {
|
|
// local인 경우 로그인 못한다고 하세요.
|
|
resultUser.reason = 'no user found';
|
|
resultUser.code = -1;
|
|
cb(new Error(resultUser.reason), resultUser);
|
|
// crossCtl.logUserAction('anonym', '404', 'bad login id, type = ' + type + ', key = ' + key + ', token = ' + token)
|
|
} else {
|
|
// 외부인 경우 레코드를 생성하고 리턴 합니다.
|
|
prefDataJson.account_info = info;
|
|
|
|
// console.log('info =', info)
|
|
// console.log('info.displayName =', info.displayName)
|
|
var post = {
|
|
site_id: crossCtl.sConfig.type,
|
|
name: info.name,
|
|
auth_type: type,
|
|
auth_key: key,
|
|
auth_token: token,
|
|
pref_data: JSON.stringify(prefDataJson),
|
|
};
|
|
qry =
|
|
'INSERT INTO ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users SET ? ';
|
|
crossCtl.db.doEasyQueryPost(qry, post, function (err, results) {
|
|
if (err) {
|
|
resultUser.reason = err.message;
|
|
resultUser.code = utils.__line();
|
|
cb(err, resultUser);
|
|
} else {
|
|
var serial = results.insertId;
|
|
var uid = utils.uuid('uid_' + serial);
|
|
crossCtl.logUserAction(uid, 'new', JSON.stringify(info));
|
|
qry =
|
|
'UPDATE ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users SET uid = ' +
|
|
mysql.escape(uid) +
|
|
' WHERE serial = ' +
|
|
serial;
|
|
crossCtl.db.doEasyQuery(qry, function (err, results) {
|
|
if (err) {
|
|
cb(err, null);
|
|
} else {
|
|
var user = {
|
|
site_id: crossCtl.sConfig.type,
|
|
uid: uid,
|
|
name: post.name,
|
|
auth_flag: true,
|
|
user_info: info,
|
|
account_info: post,
|
|
prefDataJson: prefDataJson,
|
|
newAccountFlag: true,
|
|
created: moment.utc().format(),
|
|
};
|
|
crossCtl.passEventToLocalHandler(
|
|
'addUser',
|
|
user,
|
|
function (error) {
|
|
if (error) {
|
|
utils.log(
|
|
'error',
|
|
'on crossCtl.passEventToLocalHandler(), error =',
|
|
error
|
|
);
|
|
}
|
|
if (crossCtl.sConfig.allowSignup === false) {
|
|
resultUser.reason = 'no signup allowded';
|
|
resultUser.code = -10;
|
|
cb(new Error(resultUser.reason), resultUser);
|
|
} else {
|
|
crossCtl.loadProfile(user, cb);
|
|
// cb(error, user)
|
|
}
|
|
}
|
|
);
|
|
// crossCtl.logUserAction(uid, 'login', 'login ok')
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
} else if (results.length > 1) {
|
|
resultUser.reason = 'too many target';
|
|
resultUser.code = utils.__line();
|
|
cb(new Error('too many target account found'), resultUser);
|
|
} else {
|
|
// 1개의 레코드가 있군요. 비교하세요.
|
|
if (type === 0) {
|
|
if (results[0].status !== 0) {
|
|
resultUser.reason = 'bad status : ' + results[0].status;
|
|
resultUser.code = -2;
|
|
cb(new Error(resultUser.reason), resultUser);
|
|
} else if (results[0].bad_pass_count >= 5) {
|
|
resultUser.reason =
|
|
'wrong password count limit exceeded : ' +
|
|
results[0].bad_pass_count;
|
|
resultUser.code = -2;
|
|
cb(new Error(resultUser.reason), resultUser);
|
|
} else {
|
|
utils.compareHash(
|
|
token,
|
|
results[0].auth_token,
|
|
function (err, result) {
|
|
if (err) {
|
|
resultUser.reason = err.message;
|
|
resultUser.code = utils.__line();
|
|
cb(err, resultUser);
|
|
} else {
|
|
if (result === false) {
|
|
resultUser.reason = 'bad password';
|
|
resultUser.code = -2;
|
|
cb(new Error(resultUser.reason), resultUser);
|
|
qry =
|
|
'UPDATE ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users SET bad_pass_count = bad_pass_count + 1 WHERE auth_type = ' +
|
|
type +
|
|
' AND auth_key = ' +
|
|
mysql.escape(key) +
|
|
' AND site_id = ' +
|
|
mysql.escape(crossCtl.sConfig.type);
|
|
crossCtl.db.doEasyQuery(qry, function (err, results) {});
|
|
} else {
|
|
var prefDataJson = utils.safeJSON(results[0].pref_data);
|
|
|
|
qry =
|
|
'UPDATE ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users SET bad_pass_count = 0 WHERE auth_type = ' +
|
|
type +
|
|
' AND auth_key = ' +
|
|
mysql.escape(key) +
|
|
' AND site_id = ' +
|
|
mysql.escape(crossCtl.sConfig.type);
|
|
crossCtl.db.doEasyQuery(qry, function (err, results) {});
|
|
|
|
|
|
if (prefDataJson.newAccountFlag === true) {
|
|
// console.log('huk new user!!!')
|
|
prefDataJson.newAccountFlag = undefined;
|
|
var newPrefDataJson = utils.safeJSON(
|
|
JSON.stringify(prefDataJson)
|
|
);
|
|
crossCtl.saveUserPrefData(
|
|
results[0].uid,
|
|
newPrefDataJson,
|
|
function (error, json) {
|
|
var user = {
|
|
site_id: crossCtl.sConfig.type,
|
|
uid: results[0].uid,
|
|
name: results[0].name,
|
|
auth_flag: true,
|
|
user_info: json.account_info,
|
|
account_info: results[0],
|
|
prefDataJson: json,
|
|
newAccountFlag: true,
|
|
created: results[0].created,
|
|
};
|
|
crossCtl.loadProfile(user, cb);
|
|
//cb(null, user)
|
|
}
|
|
);
|
|
} else {
|
|
var user = {
|
|
site_id: crossCtl.sConfig.type,
|
|
uid: results[0].uid,
|
|
name: results[0].name,
|
|
auth_flag: true,
|
|
user_info: prefDataJson.account_info,
|
|
account_info: results[0],
|
|
prefDataJson: prefDataJson,
|
|
created: results[0].created,
|
|
};
|
|
crossCtl.loadProfile(user, cb);
|
|
//cb(null, user)
|
|
}
|
|
// crossCtl.logUserAction(results[0].uid, 'login', 'login ok')
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
} else {
|
|
// 그냥 업데이트 해 주고 다음으로 이동...
|
|
prefDataJson = utils.safeJSON(results[0].pref_data);
|
|
if (type == 4) {
|
|
info = prefDataJson.account_info;
|
|
} else {
|
|
prefDataJson.account_info = info;
|
|
}
|
|
|
|
if (token === results[0].auth_token) {
|
|
// utils.log('external auth token match!')
|
|
} else {
|
|
// utils.log('external auth token not match!')
|
|
// utils.log('token = ' + token)
|
|
// utils.log('results[0].auth_token = ' + results[0].auth_token)
|
|
qry =
|
|
'UPDATE ' +
|
|
crossCtl.db.options.database +
|
|
'.tbl_account_users SET auth_token = ' +
|
|
mysql.escape(token) +
|
|
', pref_data = ' +
|
|
mysql.escape(JSON.stringify(prefDataJson)) +
|
|
' WHERE serial = ' +
|
|
results[0].serial;
|
|
crossCtl.db.doEasyQuery(qry, function (err, results) {
|
|
if (err) {
|
|
utils.log('error', 'doAuth(), update error. ' + err);
|
|
}
|
|
});
|
|
}
|
|
var user = {
|
|
site_id: crossCtl.sConfig.type,
|
|
uid: results[0].uid,
|
|
name: results[0].name,
|
|
auth_flag: true,
|
|
user_info: info,
|
|
account_info: results[0],
|
|
prefDataJson: prefDataJson,
|
|
created: results[0].created,
|
|
};
|
|
crossCtl.loadProfile(user, cb);
|
|
// cb(null, user)
|
|
// crossCtl.logUserAction(results[0].uid, 'login', 'login ok')
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
passport.use(
|
|
new LocalStrategy(passportOptions.local, function (
|
|
req,
|
|
email,
|
|
password,
|
|
done
|
|
) {
|
|
var normalizeUserInfo = crossCtl.normalizeUserInfo('id/password', {
|
|
email,
|
|
password,
|
|
});
|
|
console.log('normalizeUserInfo=', normalizeUserInfo);
|
|
doAuth(0, email, password, normalizeUserInfo, function (error, user) {
|
|
if (error) {
|
|
utils.log('error', 'doAuth for local error. ' + error);
|
|
}
|
|
return done(error, user);
|
|
});
|
|
})
|
|
);
|
|
|
|
passport.use(
|
|
'api-login',
|
|
new CustomStrategy(function (req, done) {
|
|
|
|
|
|
if (req.body.info == undefined) {
|
|
req.body.info = {};
|
|
}
|
|
|
|
var type = parseInt(req.body.type);
|
|
var id = req.body.id;
|
|
var token = req.body.token;
|
|
var profile =
|
|
req.body.info['provider'] != undefined
|
|
? req.body.info
|
|
: utils.safeJSON(req.body.info);
|
|
|
|
doAuth(type, id, token, profile, function (error, user) {
|
|
if (error) {
|
|
utils.log('error', 'doAuth for local error. ' + error);
|
|
}
|
|
return done(error, user);
|
|
});
|
|
})
|
|
);
|
|
|
|
var request = require('request');
|
|
|
|
passport.serializeUser(function (user, done) {
|
|
|
|
done(null, user);
|
|
});
|
|
|
|
passport.deserializeUser(function (user, done) {
|
|
|
|
done(null, user);
|
|
});
|
|
|
|
|
|
var addRequestId = require('express-request-id')();
|
|
app.use(addRequestId);
|
|
|
|
app.use(function (req, res, next) {
|
|
if (req.url !== '/ping') {
|
|
req.workTag = utils.getWorkTag(req, res);
|
|
req.workTag.responsePacket = {
|
|
header: crossCtl.config.header.responseTag,
|
|
responseCode: 0,
|
|
responseMessage: 'ok',
|
|
};
|
|
}
|
|
next();
|
|
});
|
|
|
|
app.use(function (req, res, next) {
|
|
|
|
req.uid = req.isAuthenticated()
|
|
? req.user.uid
|
|
: utils.uuid('uid_' + req.sessionID);
|
|
|
|
var userNick = '';
|
|
var userName = '';
|
|
var userEmail = '';
|
|
var provider = 'anoymous'; // facebook, google, anoymous
|
|
var adminFlag = false;
|
|
var profileUrl = '';
|
|
var messageCount = 0;
|
|
|
|
if (req.isAuthenticated() && req.user.auth_flag) {
|
|
var params = req.user;
|
|
|
|
// console.log('req.user=', req.user)
|
|
|
|
adminFlag = params.account_info.user_level === 5 ? true : false;
|
|
|
|
if (params.user_info == undefined) {
|
|
params.user_info = {};
|
|
}
|
|
|
|
provider = params.user_info.provider
|
|
? params.user_info.provider
|
|
: 'id/password'; // facebook, google
|
|
if (params.user_info.provider === 'facebook') {
|
|
userNick = 'f ' + params.user_info.name;
|
|
userName = '' + params.user_info.name;
|
|
userEmail = '';
|
|
} else if (params.user_info.provider === 'google') {
|
|
userNick = 'g+ ' + params.account_info.name;
|
|
userName = '' + params.account_info.name;
|
|
userEmail = params.user_info.email;
|
|
profileUrl = params.user_info.photo;
|
|
} else if (params.user_info.provider === 'kakao') {
|
|
userNick = 'k ' + params.user_info.name;
|
|
userName = '' + params.user_info.name;
|
|
userEmail = '' + params.user_info.email;
|
|
profileUrl = params.user_info.photo;
|
|
} else {
|
|
userNick = params.user_info.name;
|
|
userName = params.user_info.name;
|
|
userEmail = params.user_info.name;
|
|
}
|
|
} else {
|
|
userNick = 'anonym';
|
|
userName = 'anonym';
|
|
userEmail = '';
|
|
provider = 'anonymous';
|
|
}
|
|
|
|
var rawLocAry = req.originalUrl.toLowerCase().split('?');
|
|
var rawLoc = req.originalUrl.toLowerCase();
|
|
var loc = rawLocAry[0];
|
|
|
|
if (rawLoc.endsWith('/') && rawLoc !== '/') {
|
|
rawLoc = rawLoc.substring(0, rawLoc.length - 1);
|
|
}
|
|
|
|
if (loc.endsWith('/') && loc !== '/') {
|
|
loc = loc.substring(0, loc.length - 1);
|
|
}
|
|
|
|
var query = req.query;
|
|
|
|
var finalLang = 'ko';
|
|
finalLang = req.session ? (req.session.lang ? req.session.lang : 'ko') : 'ko';
|
|
finalLang = req.query.lang ? req.query.lang : finalLang;
|
|
|
|
var profile = req.isAuthenticated()
|
|
? req.user.profile
|
|
? req.user.profile
|
|
: crossCtl.makeEmptyProfile()
|
|
: crossCtl.makeEmptyProfile();
|
|
|
|
// req.infos.userInfo.userNick
|
|
req.infos = {
|
|
appInfo: {
|
|
name: crossCtl.sConfig.name,
|
|
type: crossCtl.sConfig.type,
|
|
wsUrl: crossCtl.sConfig.wsUrl,
|
|
},
|
|
|
|
hostName: utils.hostName,
|
|
|
|
fullUrl:
|
|
req.protocol + '://' + req.get('host') + req.originalUrl.toLowerCase(),
|
|
|
|
rawLoc: rawLoc,
|
|
loc: loc,
|
|
query: query,
|
|
|
|
lang: finalLang,
|
|
|
|
userInfo: {
|
|
loginFlag: req.isAuthenticated() && req.user.auth_flag,
|
|
userNick: userNick,
|
|
userName: profile.display_name,
|
|
profileUrl: profile.photo_url,
|
|
messageCount: messageCount,
|
|
adminFlag: adminFlag,
|
|
provider: provider,
|
|
fcmTokenFlag: req.session.fcmInfo == undefined ? false : true,
|
|
profile: profile,
|
|
},
|
|
|
|
localPath:
|
|
'../../../../' + crossCtl.sConfig.type + '/views/' + crossCtl.sConfig.type,
|
|
basePath: '../../../../base/views/main',
|
|
};
|
|
|
|
// console.log('req.infos=', req.infos)
|
|
// req.setLocale('ko');
|
|
|
|
// console.log('req.getLocale()=', req.getLocale())
|
|
|
|
crossCtl.i18n.setLocale(req, finalLang);
|
|
|
|
var ip = utils.getIPFromReq(req);
|
|
|
|
// console.log('ip=', ip)
|
|
// console.log('req.headers=', req.headers)
|
|
|
|
if (req.headers['x-forwarded-for']) {
|
|
if (req.headers['x-forwarded-by'] === 'bouncy') {
|
|
if (req.session) {
|
|
req.session.bouncyIP = ip;
|
|
}
|
|
} else {
|
|
if (req.session) {
|
|
req.session.bouncyIP = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (req.session.bouncyIP !== undefined) {
|
|
req.session.bouncyIP = undefined
|
|
}
|
|
*/
|
|
var ip = utils.getIPFromReq(req);
|
|
|
|
next();
|
|
});
|
|
|
|
app.use(function (req, res, next) {
|
|
var err = null;
|
|
try {
|
|
decodeURIComponent(req.path);
|
|
} catch (e) {
|
|
err = e;
|
|
}
|
|
if (err) {
|
|
// console.log(err, req.url);
|
|
utils.log(
|
|
'error',
|
|
'URI malformed. url = ' + req.url + ', req = ' + utils.dumpReq(req)
|
|
);
|
|
|
|
if (req.infos.loc.startsWith('/api/')) {
|
|
return req.workTag
|
|
.res()
|
|
.status(500)
|
|
.send({
|
|
...req.workTag.responsePacket,
|
|
responseCode: 500,
|
|
responseMessage:
|
|
'Server error : URI malformed, make sure that your filename have no % character',
|
|
});
|
|
} else {
|
|
return res.status(404).render('main/pages/next', {
|
|
infos: req.infos,
|
|
bigTitle: 404,
|
|
smallTitle:
|
|
'URI malformed, make sure that your filename have no % character',
|
|
nextTitle: 'Goto home',
|
|
nextUrl: '/',
|
|
});
|
|
}
|
|
}
|
|
next();
|
|
});
|
|
|
|
app.use(function (req, res, next) {
|
|
res.header('Access-Control-Allow-Credentials', true);
|
|
// res.header('Access-Control-Allow-Origin', req.headers.origin)
|
|
res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
|
|
// res.header('Access-Control-Allow-Origin', '*')
|
|
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
|
|
res.header(
|
|
'Access-Control-Allow-Headers',
|
|
'Origin, x-api-key, x-access-token, X-Requested-With, X-HTTP-Method-Override, Authorization, Content-Length, Content-Type, Accept, Cache-Control, DomainKey'
|
|
);
|
|
|
|
// intercepts OPTIONS method
|
|
if (req.method === 'OPTIONS') {
|
|
// respond with 200
|
|
res.sendStatus(200);
|
|
} else {
|
|
// move on
|
|
next();
|
|
}
|
|
});
|
|
|
|
app.use(function (req, res, next) {
|
|
var maintenanceInfo = crossCtl.getMaintenanceInfo();
|
|
|
|
if (maintenanceInfo !== null) {
|
|
var ip = utils.getIPFromReq(req);
|
|
|
|
if (crossCtl.isItStaffIP(ip)) {
|
|
next();
|
|
} else {
|
|
if (req.infos.loc.startsWith('/api/')) {
|
|
req.workTag
|
|
.res()
|
|
.status(503)
|
|
.send({
|
|
...req.workTag.responsePacket,
|
|
responseCode: 503,
|
|
responseMessage: 'Service Temporarily Unavailiable',
|
|
});
|
|
} else {
|
|
res.status(503).render('main/pages/next', {
|
|
infos: req.infos,
|
|
bigTitle: '점검중',
|
|
smallTitle: '준비되는대로 다시 찾아와 주세요.',
|
|
nextUrl: 'javascript:alert("꼭이요! ^o^/~")',
|
|
nextTitle: '확인',
|
|
maintenanceInfo: maintenanceInfo,
|
|
});
|
|
}
|
|
}
|
|
} else {
|
|
next();
|
|
}
|
|
});
|
|
|
|
|
|
app.options('/*', function (req, res, next) {
|
|
res.header('Access-Control-Allow-Credentials', true);
|
|
//res.header("Access-Control-Allow-Origin", req.get("Origin"));
|
|
res.header('Access-Control-Allow-Origin', req.get('Origin') || '*');
|
|
// res.header("Access-Control-Allow-Origin", req.headers.origin || "*");
|
|
// res.header('Access-Control-Allow-Origin', '*')
|
|
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
|
|
res.header(
|
|
'Access-Control-Allow-Headers',
|
|
'Origin, x-api-key, x-access-token, X-Requested-With, X-HTTP-Method-Override, Authorization, Content-Length, Content-Type, Accept, Cache-Control, DomainKey'
|
|
);
|
|
res.send(200);
|
|
|
|
});
|
|
|
|
app.use(
|
|
'/api/v1',
|
|
require('./modules/' + crossCtl.sConfig.type + '/routes/api/v1')
|
|
);
|
|
|
|
app.use(
|
|
'/api',
|
|
require('./modules/' + crossCtl.sConfig.type + '/routes/api/index')
|
|
);
|
|
app.use('/api', require('./modules/base/routes/api'));
|
|
|
|
app.use(
|
|
'/admin',
|
|
require('./modules/' + crossCtl.sConfig.type + '/routes/admin')
|
|
);
|
|
app.use('/admin', require('./modules/base/routes/admin'));
|
|
|
|
app.use('/ck', require('./modules/base/routes/ck'));
|
|
|
|
app.use('/', require('./modules/base/routes/main'));
|
|
app.use('/', require('./modules/' + crossCtl.sConfig.type + '/routes/main'));
|
|
|
|
// catch 404 and forward to error handler
|
|
app.use(function (req, res, next) {
|
|
// var err = new Error('Not Found')
|
|
// err.status = 404
|
|
// next(err)
|
|
if (req.infos.loc.startsWith('/api/')) {
|
|
req.workTag
|
|
.res()
|
|
.status(404)
|
|
.send({
|
|
...req.workTag.responsePacket,
|
|
responseCode: 404,
|
|
responseMessage: 'api not found',
|
|
});
|
|
} else {
|
|
res.status(404).render('main/pages/next', {
|
|
infos: req.infos,
|
|
bigTitle: 404,
|
|
smallTitle: 'Page not found',
|
|
nextTitle: 'Goto home',
|
|
nextUrl: '/',
|
|
});
|
|
}
|
|
});
|
|
|
|
app.use(function (err, req, res, next) {
|
|
utils.log('error', 'app trap error ' + err.stack);
|
|
utils.log('error', 'exit process after 3 sec ');
|
|
crossCtl.boom.flushAll(function (count) {
|
|
console.log(count, 'boom flushed...');
|
|
setTimeout(function () {
|
|
process.exit(1);
|
|
}, 1000);
|
|
});
|
|
});
|
|
|
|
process.on('uncaughtException', function (err) {
|
|
utils.log('error', 'uncaughtException, error ' + err.stack);
|
|
utils.log('error', 'exit process after 3 sec ');
|
|
crossCtl.boom.flushAll(function (count) {
|
|
console.log(count, 'boom flushed...');
|
|
setTimeout(function () {
|
|
process.exit(1);
|
|
}, 1000);
|
|
});
|
|
});
|
|
|
|
process.on('SIGINT', function () {
|
|
console.log('Caught interrupt signal');
|
|
utils.log('error', 'exit process after 3 sec ');
|
|
crossCtl.boom.flushAll(function (count) {
|
|
console.log(count, 'boom flushed...');
|
|
setTimeout(function () {
|
|
process.exit(1);
|
|
}, 1000);
|
|
});
|
|
});
|
|
|
|
process.on('SIGTERM', function () {
|
|
console.log('Caught term signal');
|
|
utils.log('error', 'exit process after 3 sec ');
|
|
crossCtl.boom.flushAll(function (count) {
|
|
console.log(count, 'boom flushed...');
|
|
setTimeout(function () {
|
|
process.exit(1);
|
|
}, 1000);
|
|
});
|
|
});
|
|
|
|
// error handler
|
|
/*
|
|
app.use(function (err, req, res, next) {
|
|
// set locals, only providing error in development
|
|
res.locals.message = err.message
|
|
res.locals.error = req.app.get('env') === 'development' ? err : {}
|
|
|
|
// render the error page
|
|
res.status(err.status || 500)
|
|
res.render('error')
|
|
})
|
|
*/
|
|
|
|
module.exports = app;
|