Frontend: - Replace Next.js with Vite + React + TypeScript - Add new component architecture (app-shell, sidebar, dashboard modules) - Implement product modules: FRAME, safety protocols, walkthrough checkin, campus/staff attendance, personality quiz, sign language, classroom timer - Add shadcn/ui component library with Tailwind CSS - Remove legacy generated components, stores, and pages Backend: - Add product migrations: frame_entries, user_progress, safety_quiz_results, walkthrough_checkins, communication_events, personality_quiz_results, campus_attendance_config/summaries, staff_attendance_records, content_catalog - Add corresponding models, services, and routes - Implement cookie-based auth with refresh token rotation - Add content catalog seeder with product content - Migrate to ESLint flat config - Switch from yarn to npm Infrastructure: - Update .gitignore for new tooling - Add project documentation (CLAUDE.md, docs/) - Remove deprecated config files and yarn.lock Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
62 lines
1.8 KiB
JavaScript
62 lines
1.8 KiB
JavaScript
const config = require('../config');
|
|
const providers = config.providers;
|
|
const db = require('../db/models');
|
|
const { extractAccessCookie } = require('./cookies');
|
|
|
|
const passport = require('passport');
|
|
const JWTstrategy = require('passport-jwt').Strategy;
|
|
const GoogleStrategy = require('passport-google-oauth2').Strategy;
|
|
const MicrosoftStrategy = require('passport-microsoft').Strategy;
|
|
const UsersDBApi = require('../db/api/users');
|
|
|
|
|
|
passport.use(new JWTstrategy({
|
|
passReqToCallback: true,
|
|
secretOrKey: config.secret_key,
|
|
jwtFromRequest: extractAccessCookie
|
|
}, async (req, token, done) => {
|
|
try {
|
|
const user = await UsersDBApi.findBy( {email: token.user.email});
|
|
|
|
if (user && user.disabled) {
|
|
return done (new Error(`User '${user.email}' is disabled`));
|
|
}
|
|
|
|
req.currentUser = user;
|
|
|
|
return done(null, user);
|
|
} catch (error) {
|
|
done(error);
|
|
}
|
|
}));
|
|
|
|
passport.use(new GoogleStrategy({
|
|
clientID: config.google.clientId,
|
|
clientSecret: config.google.clientSecret,
|
|
callbackURL: config.apiUrl + '/auth/signin/google/callback',
|
|
passReqToCallback: true
|
|
},
|
|
function (request, accessToken, refreshToken, profile, done) {
|
|
socialStrategy(profile.email, profile, providers.GOOGLE, done);
|
|
}
|
|
));
|
|
|
|
|
|
passport.use(new MicrosoftStrategy({
|
|
clientID: config.microsoft.clientId,
|
|
clientSecret: config.microsoft.clientSecret,
|
|
callbackURL: config.apiUrl + '/auth/signin/microsoft/callback',
|
|
passReqToCallback: true
|
|
},
|
|
function (request, accessToken, refreshToken, profile, done) {
|
|
const email = profile._json.mail || profile._json.userPrincipalName;
|
|
socialStrategy(email, profile, providers.MICROSOFT, done);
|
|
}
|
|
));
|
|
|
|
function socialStrategy(email, profile, provider, done) {
|
|
db.users.findOrCreate({where: {email, provider}}).then(([user]) => {
|
|
return done(null, {user});
|
|
});
|
|
}
|