UNPKG

very-express

Version:

based on json schema and openapi, generate Express RestApi server with mongoDb

87 lines (74 loc) 3.01 kB
// {{headerComment}} import { UserModel, UserDocument } from "./../../_models/UserModel.gen"; import { User } from "./../../_types/User.gen"; import profileMapping, { IProfile } from "./profileMapping.gen"; import { sanitizeUser } from "./token.gen"; import vex from "../../_utils/index.gen"; export default async function oauthVerify(accessToken: string, refreshToken: string, profile: IProfile, done: (error: any, user?: any) => void) : Promise<void> { try { let user: UserDocument; const authUser = profileMapping(profile); // find user by authProfiles.authId or email const existingUser = await UserModel.findOne<UserDocument>({ email: authUser.email, $or: authUser.authProfiles?.map((p) => { return { "authProfiles.authId": p.authId }; }), }); // 1. create new user if ( !existingUser ){ user = await createNewUser(authUser); } // 2. update existing user else { console.log("OAuthVerify UpdateUser"); user = await processExistingUser(authUser, existingUser); } // set req.user done(null, { provider: profile.provider, profile: sanitizeUser(user), }); } catch(err) { return done(err); } } async function createNewUser(authProfile: User): Promise<UserDocument>{ vex.log.info("OAuthVerify > createNewUser"); const newUser = new UserModel(authProfile); return await newUser.save(); } async function processExistingUser( authUser: User, existingUser: UserDocument): Promise<UserDocument>{ vex.log.info("OAuthVerify > processExistingUser"); let userUpdated = false; const authProfile = authUser.authProfiles?.[0] || undefined; const userProfiles = existingUser.authProfiles as User["authProfiles"] || []; if(!authProfile){ vex.log.errorNoExit("OAuthVerify > Invalid OAuth Callback \"authProfile\""); throw new Error("Invalid OAuth Callback \"authProfile\""); } // B.1. check current provider exist in authProfiles const providerExists = userProfiles.length > 0 && userProfiles.find((p) => { return (p.provider === authProfile.provider) && (p.authId === authProfile.authId); }); // B.2. add if not exist if (!providerExists){ vex.log.info("OAuthVerify > add new provider",authProfile.provider); userProfiles.push(authProfile); userUpdated = true; } // B.3 update if username changed else if (providerExists && providerExists.username !== authProfile.username){ vex.log.info("OAuthVerify > update username", authProfile.provider); providerExists.username = authProfile.username; userUpdated = true; } if (userUpdated){ vex.log.info("OAuthVerify > Update user"); return await existingUser.updateOne({ authProfiles: userProfiles }); } else { return existingUser; } }