import * as plugins from '../plugins.js'; import { RegistrationSession } from './classes.registrationsession.js'; import { Reception } from './classes.reception.js'; import { logger } from './logging.js'; export class RegistrationSessionManager { public receptionRef: Reception; public typedRouter = new plugins.typedrequest.TypedRouter(); public get db() { return this.receptionRef.db.smartdataDb; } public CRegistrationSession = plugins.smartdata.setDefaultManagerForDoc(this, RegistrationSession); constructor(receptionRefArg: Reception) { this.receptionRef = receptionRefArg; this.receptionRef.typedrouter.addTypedRouter(this.typedRouter); this.typedRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'firstRegistrationRequest', async (requestData) => { // check for exiting User const existingUser = await this.receptionRef.userManager.CUser.getInstance({ data: { email: requestData.email, }, }); if (existingUser) { this.receptionRef.receptionMailer.sendAlreadyRegisteredEmail(existingUser); throw new plugins.typedrequest.TypedResponseError( `We sent you an Email with more information.` ); } const existingSessions = await this.CRegistrationSession.getInstances({ 'data.emailAddress': requestData.email, }); for (const existingSession of existingSessions) { logger.log('warn', `destroyed old signupSession for ${requestData.email}`); await existingSession.destroy(); } const newSignupSession = await RegistrationSession.createRegistrationSessionForEmail( requestData.email ).catch((e: plugins.typedrequest.TypedResponseError) => { console.log(e.errorText); throw e; }); if (newSignupSession) { logger.log('info', `created signupSession for ${requestData.email}`); return { status: 'ok', testOnlyToken: process.env.TEST_MODE ? newSignupSession.unhashedEmailToken : null, }; } else { return { status: 'not ok' }; } } ) ); this.typedRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'afterRegistrationEmailClicked', async (requestData) => { const signupSession = await this.findRegistrationSessionByToken(requestData.token); if (signupSession) { return { email: signupSession.emailAddress, status: 'ok', }; } else { return { email: null, status: 'not ok', }; } } ) ); this.typedRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'setDataForRegistration', async (requestData) => { const registrationSession = await this.findRegistrationSessionByToken(requestData.token); if (!registrationSession) { throw new plugins.typedrequest.TypedResponseError( 'could not find a matching signupsession' ); } if (requestData.userData.name) { registrationSession.collectedData.userData.name = requestData.userData.name; } if (requestData.userData.password) { registrationSession.collectedData.userData.password = requestData.userData.password; } return { status: 'ok', }; } ) ); this.typedRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'mobileVerificationForRegistration', async (requestData) => { const registrationSession = await this.findRegistrationSessionByToken(requestData.token); if (!registrationSession) { throw new plugins.typedrequest.TypedResponseError( 'could not find a matching signupsession' ); } // check prerequisites if (registrationSession.status === 'announced') { throw new plugins.typedrequest.TypedResponseError( 'You must validate the email address first' ); } if (requestData.mobileNumber) { registrationSession.collectedData.userData.mobileNumber = requestData.mobileNumber; const smsCode = await registrationSession.sendValidationSms(); return { messageSent: true, testOnlySmsCode: process.env.TEST_MODE ? smsCode : null, }; } if (requestData.verificationCode) { const validationResult = await registrationSession.validateSmsCode( requestData.verificationCode ); return { verficationCodeOk: validationResult, }; } throw new plugins.typedrequest.TypedResponseError( 'you misused the purpose of this TypedHandler' ); } ) ); this.typedRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'finishRegistration', async (requestData) => { const registrationSession = await this.findRegistrationSessionByToken(requestData.token); if (!registrationSession) { throw new plugins.typedrequest.TypedResponseError( 'could not find a matching signupsession' ); } const resultingUser = await registrationSession.manifestUserWithAccountData(); await registrationSession.destroy(); this.receptionRef.receptionMailer.sendWelcomeEMail(resultingUser); return { accountData: { id: resultingUser.id, data: { email: resultingUser.data.email, name: resultingUser.data.name, username: resultingUser.data.username, }, }, status: 'ok', }; } ) ); } public async findRegistrationSessionByToken(tokenArg: string) { const registrationSession = await this.CRegistrationSession.getInstance({ 'data.hashedEmailToken': RegistrationSession.hashToken(tokenArg), }); if (!registrationSession) { return null; } const isValid = await registrationSession.validateEmailToken(tokenArg); return isValid ? registrationSession : null; } }