157 lines
4.3 KiB
JavaScript
157 lines
4.3 KiB
JavaScript
require('dotenv').config();
|
|
|
|
const express = require('express');
|
|
const session = require('express-session');
|
|
const expressLayouts = require('express-ejs-layouts');
|
|
const cookieParser = require('cookie-parser');
|
|
const RedisStore = require('connect-redis').default;
|
|
const redis = require('redis');
|
|
const passport = require('passport');
|
|
const DiscordStrategy = require('passport-discord').Strategy;
|
|
const { sequelize, User } = require('./models');
|
|
const setupWebSocketServer = require('./websocket');
|
|
|
|
const authRoutes = require('./routes/authRoutes');
|
|
const chatRoutes = require('./routes/chatRoutes');
|
|
const isotopeRoutes = require('./routes/isotopeRoutes');
|
|
const accountRoutes = require('./routes/accountRoutes');
|
|
const dashboardRoutes = require('./routes/dashboardRoutes');
|
|
const licenseRoutes = require('./routes/licenseRoutes');
|
|
|
|
const http = require('http');
|
|
const WebSocket = require('ws');
|
|
const app = express();
|
|
const server = http.createServer(app);
|
|
const wss = new WebSocket.Server({ noServer: true });
|
|
|
|
// 必要な環境変数の確認
|
|
const requiredEnvVariables = [
|
|
'REDIS_HOST',
|
|
'REDIS_PORT',
|
|
'REDIS_PASSWORD',
|
|
'SESSION_SECRET',
|
|
'SESSION_EXPIRATION',
|
|
'DISCORD_CLIENT_ID',
|
|
'DISCORD_CLIENT_SECRET',
|
|
'DISCORD_REDIRECT_URI'
|
|
];
|
|
requiredEnvVariables.forEach((envVar) => {
|
|
if (!process.env[envVar]) {
|
|
throw new Error(`環境変数 ${envVar} が設定されていません。`);
|
|
}
|
|
});
|
|
|
|
// Redisクライアントを作成
|
|
const redisClient = redis.createClient({
|
|
url: `redis://:${process.env.REDIS_PASSWORD}@${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`
|
|
});
|
|
redisClient.on('error', (err) => {
|
|
console.log('Redis Client Error', err);
|
|
process.exit(1);
|
|
});
|
|
redisClient.connect().then(() => {
|
|
console.log('Connected to Redis');
|
|
});
|
|
|
|
// Redis セッションストアの設定
|
|
const sessionMiddleware = session({
|
|
store: new RedisStore({ client: redisClient }),
|
|
secret: process.env.SESSION_SECRET,
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
cookie: { maxAge: parseInt(process.env.SESSION_EXPIRATION) * 1000 }
|
|
});
|
|
app.use(sessionMiddleware);
|
|
|
|
// Cookie パーサーの設定
|
|
app.use(cookieParser());
|
|
// パスポートの初期化
|
|
app.use(passport.initialize());
|
|
app.use(passport.session());
|
|
|
|
// WebSocket と Express セッションの連携
|
|
server.on('upgrade', (request, socket, head) => {
|
|
sessionMiddleware(request, {}, () => {
|
|
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
wss.emit('connection', ws, request);
|
|
});
|
|
});
|
|
});
|
|
|
|
// パスポートのDiscord戦略設定
|
|
passport.use(new DiscordStrategy({
|
|
clientID: process.env.DISCORD_CLIENT_ID,
|
|
clientSecret: process.env.DISCORD_CLIENT_SECRET,
|
|
callbackURL: process.env.DISCORD_REDIRECT_URI,
|
|
scope: ['identify', 'email']
|
|
}, async (accessToken, refreshToken, profile, done) => {
|
|
try {
|
|
let user = await User.findOne({ where: { discordId: profile.id } });
|
|
if (user) {
|
|
return done(null, user);
|
|
} else {
|
|
user = await User.create({
|
|
discordId: profile.id,
|
|
username: profile.username,
|
|
email: profile.email,
|
|
isAccountSetupComplete: false
|
|
});
|
|
return done(null, user);
|
|
}
|
|
} catch (err) {
|
|
return done(err, null);
|
|
}
|
|
}));
|
|
|
|
// シリアライズとデシリアライズ
|
|
passport.serializeUser((user, done) => {
|
|
done(null, user.id);
|
|
});
|
|
|
|
passport.deserializeUser(async (id, done) => {
|
|
try {
|
|
const user = await User.findByPk(id);
|
|
done(null, user);
|
|
} catch (err) {
|
|
done(err, null);
|
|
}
|
|
});
|
|
|
|
// JSON形式のリクエストボディをパースするミドルウェアを追加
|
|
app.use(express.json());
|
|
app.use(express.urlencoded({ extended: true }));
|
|
|
|
app.use(express.static('public'));
|
|
|
|
app.set('view engine', 'ejs');
|
|
app.use(expressLayouts);
|
|
app.set('layout', 'layout');
|
|
|
|
// ルート設定
|
|
app.use(authRoutes);
|
|
app.use(chatRoutes);
|
|
app.use(isotopeRoutes);
|
|
app.use(accountRoutes);
|
|
app.use(dashboardRoutes);
|
|
app.use(licenseRoutes);
|
|
|
|
app.get('/', (req, res) => {
|
|
if (req.isAuthenticated()) {
|
|
res.redirect('/dashboard');
|
|
} else {
|
|
// layoutを使わずにindex.ejsだけを表示
|
|
res.render('index', { layout: false });
|
|
}
|
|
});
|
|
|
|
// WebSocketサーバーのセットアップ
|
|
setupWebSocketServer(wss);
|
|
|
|
// サーバーの起動
|
|
(async () => {
|
|
await sequelize.sync();
|
|
server.listen(3000, () => {
|
|
console.log('サーバーがhttp://localhost:3000で起動しました。');
|
|
});
|
|
})();
|