import { IdpGlobalServerClient } from './classes.idp-global-server-client.js'; import { SmartdataAccountStore } from './classes.account-store.js'; import type { IAuthenticateAccountOptions, IAuthenticatedAccountResult, IIdpSdkAccount } from './interfaces.js'; export class AccountAuthService { constructor(private optionsArg: { store: SmartdataAccountStore; idpClient?: IdpGlobalServerClient; }) {} public async authenticate(optionsArg: IAuthenticateAccountOptions): Promise { const account = await this.optionsArg.store.getAccountByEmail(optionsArg.email); if (!account || account.status !== 'active') { return null; } const authSource = optionsArg.authSource || 'auto'; if ((authSource === 'local' || authSource === 'auto') && account.authSources.includes('local')) { const localOk = await this.optionsArg.store.verifyLocalPassword(account, optionsArg.password); if (localOk) { const updatedAccount = await this.optionsArg.store.updateLoginState(account.id, {}); return { account: updatedAccount || account, authSource: 'local' }; } if (authSource === 'local') { return null; } } if ((authSource === 'idp.global' || authSource === 'auto') && account.authSources.includes('idp.global')) { return this.authenticateWithIdp(account, optionsArg.password); } return null; } private async authenticateWithIdp(accountArg: IIdpSdkAccount, passwordArg: string): Promise { if (!this.optionsArg.idpClient) { return null; } const idpResult = await this.optionsArg.idpClient.loginWithEmailAndPassword({ email: accountArg.email, password: passwordArg, }); const idpEmail = this.optionsArg.store.normalizeEmail(idpResult.user.data.email); if (idpEmail !== accountArg.emailNormalized) { return null; } if (accountArg.idpSubject && accountArg.idpSubject !== idpResult.user.id) { return null; } const updatedAccount = await this.optionsArg.store.updateLoginState(accountArg.id, { idpSubject: accountArg.idpSubject || idpResult.user.id, }); return { account: updatedAccount || accountArg, authSource: 'idp.global', idpJwt: idpResult.jwt, idpRefreshToken: idpResult.refreshToken, }; } }