Files
sdk/ts_server/classes.account-auth-service.ts
T

62 lines
2.3 KiB
TypeScript
Raw Normal View History

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<IAuthenticatedAccountResult | null> {
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<IAuthenticatedAccountResult | null> {
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,
};
}
}