import * as plugins from '../plugins.js'; import type { Cloudly } from '../classes.cloudly.js'; import { logger } from '../logger.js'; import { Authorization } from './classes.authorization.js'; import { User } from './classes.user.js'; export interface IJwtData { userId: string; status: 'loggedIn' | 'loggedOut'; } export class CloudlyAuthManager { cloudlyRef: Cloudly public get db() { return this.cloudlyRef.mongodbConnector.smartdataDb; } public CUser = plugins.smartdata.setDefaultManagerForDoc(this, User); public CAuthorization = plugins.smartdata.setDefaultManagerForDoc(this, Authorization); public typedrouter = new plugins.typedrequest.TypedRouter(); public smartjwtInstance: plugins.smartjwt.SmartJwt; constructor(cloudlyRef: Cloudly) { this.cloudlyRef = cloudlyRef; this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter); } public async start() { // lets setup the smartjwtInstance this.smartjwtInstance = new plugins.smartjwt.SmartJwt(); await this.smartjwtInstance.init(); const kvStore = await this.cloudlyRef.config.appData.getKvStore(); const existingJwtKeys: plugins.tsclass.network.IJwtKeypair = await kvStore.readKey('jwtKeys'); if (!existingJwtKeys) { await this.smartjwtInstance.createNewKeyPair(); const newJwtKeys = this.smartjwtInstance.getKeyPairAsJson(); await kvStore.writeKey('jwtKeys', newJwtKeys); } else { this.smartjwtInstance.setKeyPairAsJson(existingJwtKeys); } this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'adminLoginWithUsernameAndPassword', async (dataArg) => { let jwt: string; const user = await User.findUserByUsernameAndPassword(dataArg.username, dataArg.password); if (!user) { logger.log('warn', 'login failed'); } else { jwt = await this.smartjwtInstance.createJWT({ userId: user.id, status: 'loggedIn', }); logger.log('success', 'login successful'); } return { jwt, }; } ) ); } public async stop () {} public adminJwtGuard = new plugins.smartguard.Guard<{jwt: string}>(async (dataArg) => { const jwt = dataArg.jwt; const jwtData: IJwtData = await this.smartjwtInstance.verifyJWTAndGetData(jwt); const user = await this.CUser.getInstance({id: jwtData.userId}); const isAdminBool = user.data.role === 'admin'; console.log(`user is admin: ${isAdminBool}`); return isAdminBool; }, { failedHint: 'user is not admin.' }) }