diff --git a/apps/vben5/apps/app-antd/src/adapter/request/index.ts b/apps/vben5/apps/app-antd/src/adapter/request/index.ts index e0c13d6a5..41a3415a4 100644 --- a/apps/vben5/apps/app-antd/src/adapter/request/index.ts +++ b/apps/vben5/apps/app-antd/src/adapter/request/index.ts @@ -37,7 +37,8 @@ export function initRequestClient() { async function doRefreshToken() { const authStore = useAuthStore(); try { - return await authStore.refreshSession(); + const token = await authStore.refreshSession(); + return token ?? ''; } catch { console.warn('The refresh token has expired or is unavailable.'); } diff --git a/apps/vben5/apps/app-antd/src/store/auth.ts b/apps/vben5/apps/app-antd/src/store/auth.ts index c44b207ca..3b3452809 100644 --- a/apps/vben5/apps/app-antd/src/store/auth.ts +++ b/apps/vben5/apps/app-antd/src/store/auth.ts @@ -9,14 +9,7 @@ import { LOGIN_PATH } from '@vben/constants'; import { preferences } from '@vben/preferences'; import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; -import { - useOidcClient, - usePhoneLoginApi, - useProfileApi, - useQrCodeLoginApi, - useTokenApi, - useUserInfoApi, -} from '@abp/account'; +import { useOAuthService, useProfileApi } from '@abp/account'; import { Events, useAbpStore, useEventBus } from '@abp/core'; import { notification } from 'ant-design-vue'; import { defineStore } from 'pinia'; @@ -26,48 +19,35 @@ import { $t } from '#/locales'; export const useAuthStore = defineStore('auth', () => { const { publish } = useEventBus(); - const { loginApi, refreshTokenApi, logoutApi } = useTokenApi(); - const { loginApi: qrcodeLoginApi } = useQrCodeLoginApi(); - const { loginApi: phoneLoginApi } = usePhoneLoginApi(); - const { getUserInfoApi } = useUserInfoApi(); const { getConfigApi } = useAbpConfigApi(); const { getPictureApi } = useProfileApi(); const accessStore = useAccessStore(); const userStore = useUserStore(); const abpStore = useAbpStore(); const router = useRouter(); - const oidcClient = useOidcClient(); + const oAuthService = useOAuthService(); const loginLoading = ref(false); async function refreshSession() { - if (await oidcClient.getAccessToken()) { - const user = await oidcClient.refreshToken(); + if (await oAuthService.getAccessToken()) { + const user = await oAuthService.refreshToken(); const newToken = `${user?.token_type} ${user?.access_token}`; accessStore.setAccessToken(newToken); if (user?.refresh_token) { accessStore.setRefreshToken(user.refresh_token); } return newToken; - } else { - const { accessToken, tokenType, refreshToken } = await refreshTokenApi({ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - refreshToken: accessStore.refreshToken!, - }); - const newToken = `${tokenType} ${accessToken}`; - accessStore.setAccessToken(newToken); - accessStore.setRefreshToken(refreshToken); - return newToken; } } async function oidcLogin() { - await oidcClient.login(); + await oAuthService.login(); } async function oidcCallback() { try { - const user = await oidcClient.handleCallback(); + const user = await oAuthService.handleCallback(); return await _loginSuccess({ accessToken: user.access_token, tokenType: user.token_type, @@ -87,8 +67,17 @@ export const useAuthStore = defineStore('auth', () => { ) { try { loginLoading.value = true; - const result = await qrcodeLoginApi({ key, tenantId }); - return await _loginSuccess(result, onSuccess); + const user = await oAuthService.loginByQrCode({ key, tenantId }); + return await _loginSuccess( + { + accessToken: user.access_token, + tokenType: user.token_type, + refreshToken: user.refresh_token ?? '', + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + expiresIn: user.expires_in!, + }, + onSuccess, + ); } finally { loginLoading.value = false; } @@ -101,8 +90,17 @@ export const useAuthStore = defineStore('auth', () => { ) { try { loginLoading.value = true; - const result = await phoneLoginApi({ phoneNumber, code }); - return await _loginSuccess(result, onSuccess); + const user = await oAuthService.loginBySmsCode({ phoneNumber, code }); + return await _loginSuccess( + { + accessToken: user.access_token, + tokenType: user.token_type, + refreshToken: user.refresh_token ?? '', + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + expiresIn: user.expires_in!, + }, + onSuccess, + ); } finally { loginLoading.value = false; } @@ -119,8 +117,17 @@ export const useAuthStore = defineStore('auth', () => { ) { try { loginLoading.value = true; - const result = await loginApi(params as any); - return await _loginSuccess(result, onSuccess); + const user = await oAuthService.loginByPassword(params as any); + return await _loginSuccess( + { + accessToken: user.access_token, + tokenType: user.token_type, + refreshToken: user.refresh_token ?? '', + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + expiresIn: user.expires_in!, + }, + onSuccess, + ); } finally { loginLoading.value = false; } @@ -128,28 +135,11 @@ export const useAuthStore = defineStore('auth', () => { async function logout(redirect: boolean = true) { try { - if (await oidcClient.getAccessToken()) { + if (await oAuthService.getAccessToken()) { accessStore.setAccessToken(null); - await oidcClient.logout(); + await oAuthService.logout(); } else { - const logoutTasks: Promise[] = []; - if (accessStore.accessToken) { - logoutTasks.push( - logoutApi({ - token: accessStore.accessToken, - tokenType: 'access_token', - }), - ); - } - if (accessStore.refreshToken) { - logoutTasks.push( - logoutApi({ - token: accessStore.refreshToken, - tokenType: 'refresh_token', - }), - ); - } - await Promise.all(logoutTasks); + await oAuthService.revokeTokens(); } } catch { // 不做任何处理 @@ -172,7 +162,11 @@ export const useAuthStore = defineStore('auth', () => { async function fetchUserInfo() { let userInfo: null | (UserInfo & { [key: string]: any }) = null; - const userInfoRes = await getUserInfoApi(); + let userInfoRes: { [key: string]: any } = {}; + const user = await oAuthService.getUser(); + if (user) { + userInfoRes = user.profile; + } const abpConfig = await getConfigApi(); const picture = await getPictureApi(); userInfo = { diff --git a/apps/vben5/packages/@abp/account/src/api/index.ts b/apps/vben5/packages/@abp/account/src/api/index.ts index 54e3e8ead..9f94ff5ed 100644 --- a/apps/vben5/packages/@abp/account/src/api/index.ts +++ b/apps/vben5/packages/@abp/account/src/api/index.ts @@ -1,7 +1,4 @@ export { useAccountApi } from './useAccountApi'; export { useMySessionApi } from './useMySessionApi'; -export { usePhoneLoginApi } from './usePhoneLoginApi'; export { useProfileApi } from './useProfileApi'; -export { useQrCodeLoginApi } from './useQrCodeLoginApi'; -export { useTokenApi } from './useTokenApi'; -export { useUserInfoApi } from './useUserInfoApi'; +export { useScanQrCodeApi } from './useScanQrCodeApi'; diff --git a/apps/vben5/packages/@abp/account/src/api/usePhoneLoginApi.ts b/apps/vben5/packages/@abp/account/src/api/usePhoneLoginApi.ts deleted file mode 100644 index 0d6be68b3..000000000 --- a/apps/vben5/packages/@abp/account/src/api/usePhoneLoginApi.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { OAuthTokenResult, PhoneNumberTokenRequest } from '../types/token'; - -import { useAppConfig } from '@vben/hooks'; - -import { useRequest } from '@abp/request'; - -export function usePhoneLoginApi() { - const { cancel, request } = useRequest(); - - /** - * 手机验证码登录 - * @param input 登录参数 - * @returns 用户token - */ - async function loginApi(input: PhoneNumberTokenRequest) { - const { audience, clientId, clientSecret } = useAppConfig( - import.meta.env, - import.meta.env.PROD, - ); - const result = await request('/connect/token', { - data: { - client_id: clientId, - client_secret: clientSecret, - grant_type: 'phone_verify', - phone_number: input.phoneNumber, - phone_verify_code: input.code, - scope: audience, - }, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - method: 'POST', - }); - return { - accessToken: result.access_token, - expiresIn: result.expires_in, - refreshToken: result.refresh_token, - tokenType: result.token_type, - }; - } - - return { - cancel, - loginApi, - }; -} diff --git a/apps/vben5/packages/@abp/account/src/api/useQrCodeLoginApi.ts b/apps/vben5/packages/@abp/account/src/api/useQrCodeLoginApi.ts deleted file mode 100644 index 3acf36957..000000000 --- a/apps/vben5/packages/@abp/account/src/api/useQrCodeLoginApi.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { - GenerateQrCodeResult, - QrCodeUserInfoResult, -} from '../types/qrcode'; -import type { OAuthTokenResult, QrCodeTokenRequest } from '../types/token'; - -import { useAppConfig } from '@vben/hooks'; - -import { useRequest } from '@abp/request'; - -export function useQrCodeLoginApi() { - const { cancel, request } = useRequest(); - - /** - * 生成登录二维码 - * @returns 二维码信息 - */ - function generateApi(): Promise { - return request('/api/account/qrcode/generate', { - method: 'POST', - }); - } - - /** - * 检查二维码状态 - * @param key 二维码Key - * @returns 二维码信息 - */ - function checkCodeApi(key: string): Promise { - return request(`/api/account/qrcode/${key}/check`, { - method: 'GET', - }); - } - - /** - * 二维码登录 - * @param input 登录参数 - * @returns 用户token - */ - async function loginApi(input: QrCodeTokenRequest) { - const { audience, clientId, clientSecret } = useAppConfig( - import.meta.env, - import.meta.env.PROD, - ); - const result = await request('/connect/token', { - data: { - client_id: clientId, - client_secret: clientSecret, - grant_type: 'qr_code', - qrcode_key: input.key, - scope: audience, - tenant_id: input.tenantId, - }, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - method: 'POST', - }); - return { - accessToken: result.access_token, - expiresIn: result.expires_in, - refreshToken: result.refresh_token, - tokenType: result.token_type, - }; - } - - return { - cancel, - checkCodeApi, - generateApi, - loginApi, - }; -} diff --git a/apps/vben5/packages/@abp/account/src/api/useScanQrCodeApi.ts b/apps/vben5/packages/@abp/account/src/api/useScanQrCodeApi.ts new file mode 100644 index 000000000..c28fff84b --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/api/useScanQrCodeApi.ts @@ -0,0 +1,37 @@ +import type { + GenerateQrCodeResult, + QrCodeUserInfoResult, +} from '../types/qrcode'; + +import { useRequest } from '@abp/request'; + +export function useScanQrCodeApi() { + const { cancel, request } = useRequest(); + + /** + * 生成登录二维码 + * @returns 二维码信息 + */ + function generateApi(): Promise { + return request('/api/account/qrcode/generate', { + method: 'POST', + }); + } + + /** + * 检查二维码状态 + * @param key 二维码Key + * @returns 二维码信息 + */ + function checkCodeApi(key: string): Promise { + return request(`/api/account/qrcode/${key}/check`, { + method: 'GET', + }); + } + + return { + cancel, + checkCodeApi, + generateApi, + }; +} diff --git a/apps/vben5/packages/@abp/account/src/api/useTokenApi.ts b/apps/vben5/packages/@abp/account/src/api/useTokenApi.ts deleted file mode 100644 index 1f8c4ac2f..000000000 --- a/apps/vben5/packages/@abp/account/src/api/useTokenApi.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type { - OAuthTokenRefreshModel, - OAuthTokenResult, - PasswordTokenRequestModel, - RevokeTokenRequest, - TokenResult, -} from '../types'; - -import { useAppConfig } from '@vben/hooks'; - -import { useRequest } from '@abp/request'; - -export function useTokenApi() { - const { cancel, request } = useRequest(); - /** - * 用户登录 - * @param input 参数 - * @returns 用户token - */ - async function loginApi( - input: PasswordTokenRequestModel, - ): Promise { - const { audience, clientId, clientSecret } = useAppConfig( - import.meta.env, - import.meta.env.PROD, - ); - const result = await request('/connect/token', { - data: { - client_id: clientId, - client_secret: clientSecret, - grant_type: 'password', - scope: audience, - ...input, - }, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - method: 'POST', - }); - return { - accessToken: result.access_token, - expiresIn: result.expires_in, - refreshToken: result.refresh_token, - tokenType: result.token_type, - }; - } - - /** - * 刷新令牌 - * @param input 参数 - * @returns 用户token - */ - async function refreshTokenApi(input: OAuthTokenRefreshModel) { - const { audience, clientId, clientSecret } = useAppConfig( - import.meta.env, - import.meta.env.PROD, - ); - const result = await request('/connect/token', { - data: { - client_id: clientId, - client_secret: clientSecret, - grant_type: 'refresh_token', - refresh_token: input.refreshToken, - scope: audience, - }, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - method: 'POST', - }); - return { - accessToken: result.access_token, - expiresIn: result.expires_in, - refreshToken: result.refresh_token, - tokenType: result.token_type, - }; - } - - /** - * 注销登录 - * @param input 参数 - */ - async function logoutApi(input: RevokeTokenRequest): Promise { - const { clientId, clientSecret } = useAppConfig( - import.meta.env, - import.meta.env.PROD, - ); - return await request('/connect/revocat', { - data: { - client_id: clientId, - client_secret: clientSecret, - token: input.token, - token_type_hint: input.tokenType, - }, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - method: 'POST', - }); - } - - return { - cancel, - loginApi, - logoutApi, - refreshTokenApi, - }; -} diff --git a/apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts b/apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts deleted file mode 100644 index aa7c5adb3..000000000 --- a/apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { OAuthUserInfo, UserInfo } from '../types/user'; - -import { useRequest } from '@abp/request'; - -export function useUserInfoApi() { - const { cancel, request } = useRequest(); - - /** - * 获取用户信息 - */ - async function getUserInfoApi(): Promise { - const result = await request('/connect/userinfo', { - method: 'GET', - }); - return { - ...result, - emailVerified: result.email_verified, - givenName: result.given_name, - phoneNumberVerified: result.phone_number_verified, - preferredUsername: result.preferred_username, - uniqueName: result.unique_name, - }; - } - - return { - cancel, - getUserInfoApi, - }; -} diff --git a/apps/vben5/packages/@abp/account/src/components/QrCodeLogin.vue b/apps/vben5/packages/@abp/account/src/components/QrCodeLogin.vue index 7c1dcddcb..192f28e54 100644 --- a/apps/vben5/packages/@abp/account/src/components/QrCodeLogin.vue +++ b/apps/vben5/packages/@abp/account/src/components/QrCodeLogin.vue @@ -11,7 +11,7 @@ import { VbenButton } from '@vben-core/shadcn-ui'; import { useQRCode } from '@vueuse/integrations/useQRCode'; import { Spin } from 'ant-design-vue'; -import { useQrCodeLoginApi } from '../api'; +import { useScanQrCodeApi } from '../api'; import { QrCodeStatus } from '../types/qrcode'; import Title from './components/LoginTitle.vue'; @@ -66,7 +66,7 @@ const emits = defineEmits<{ let interval: NodeJS.Timeout; const router = useRouter(); -const { checkCodeApi, generateApi } = useQrCodeLoginApi(); +const { checkCodeApi, generateApi } = useScanQrCodeApi(); const qrcodeInfo = ref({ key: '', diff --git a/apps/vben5/packages/@abp/account/src/hooks/index.ts b/apps/vben5/packages/@abp/account/src/hooks/index.ts index 25bce3f27..556dbb37b 100644 --- a/apps/vben5/packages/@abp/account/src/hooks/index.ts +++ b/apps/vben5/packages/@abp/account/src/hooks/index.ts @@ -1,2 +1,2 @@ export * from './useOAuthError'; -export * from './useOidcClient'; +export * from './useOAuthService'; diff --git a/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts b/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts index 972f8274d..a1e821002 100644 --- a/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts +++ b/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts @@ -23,7 +23,8 @@ export function useOAuthError() { return $t('abp.oauth.errors.requiresTwoFactor'); } // Token已失效 - case 'The token is no longer valid.': { + case 'The token is no longer valid.': + case 'The user is no longer allowed to sign in.': { return $t('abp.oauth.errors.tokenHasExpired'); } // 用户尝试登录次数太多,用户被锁定 diff --git a/apps/vben5/packages/@abp/account/src/hooks/useOidcClient.ts b/apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts similarity index 53% rename from apps/vben5/packages/@abp/account/src/hooks/useOidcClient.ts rename to apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts index f4090b44e..92e064aeb 100644 --- a/apps/vben5/packages/@abp/account/src/hooks/useOidcClient.ts +++ b/apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts @@ -1,14 +1,36 @@ +import type { + PasswordTokenRequestModel, + PhoneNumberTokenRequest, + QrCodeTokenRequest, +} from '../types/token'; + import { userManager } from '../utils/auth'; -export function useOidcClient() { +export function useOAuthService() { async function login() { return userManager.signinRedirect(); } + async function loginByPassword(input: PasswordTokenRequestModel) { + return userManager.signinResourceOwnerCredentials(input); + } + + async function loginBySmsCode(input: PhoneNumberTokenRequest) { + return userManager.signinSmsCode(input); + } + + async function loginByQrCode(input: QrCodeTokenRequest) { + return userManager.signinQrCode(input); + } + async function logout() { return userManager.signoutRedirect(); } + async function revokeTokens() { + return userManager.revokeTokens(['access_token', 'refresh_token']); + } + async function refreshToken() { return userManager.signinSilent(); } @@ -33,8 +55,12 @@ export function useOidcClient() { return { login, + loginByPassword, + loginBySmsCode, + loginByQrCode, logout, refreshToken, + revokeTokens, getAccessToken, isAuthenticated, handleCallback, diff --git a/apps/vben5/packages/@abp/account/src/types/token.ts b/apps/vben5/packages/@abp/account/src/types/token.ts index c29967c6f..653b5cde8 100644 --- a/apps/vben5/packages/@abp/account/src/types/token.ts +++ b/apps/vben5/packages/@abp/account/src/types/token.ts @@ -16,6 +16,7 @@ interface PasswordTokenRequest extends TokenRequest { } /** 手机号授权请求数据模型 */ interface PhoneNumberTokenRequest { + [key: string]: any; /** 验证码 */ code: string; /** 手机号 */ @@ -23,25 +24,27 @@ interface PhoneNumberTokenRequest { } /** 扫码登录授权请求数据模型 */ interface QrCodeTokenRequest { + [key: string]: any; /** 二维码Key */ key: string; /** 租户Id */ tenantId?: string; } -/** 令牌撤销请求数据类型 */ -interface RevokeTokenRequest { - /** 令牌 */ - token: string; - /** 令牌类型 */ - tokenType?: 'access_token' | 'refresh_token'; -} /** 用户密码授权请求数据模型 */ interface PasswordTokenRequestModel { + [key: string]: any; /** 用户密码 */ password: string; /** 用户名 */ username: string; } +/** 令牌撤销请求数据类型 */ +interface RevokeTokenRequest { + /** 令牌 */ + token: string; + /** 令牌类型 */ + tokenType?: 'access_token' | 'refresh_token'; +} /** 令牌返回数据模型 */ interface TokenResult { /** 访问令牌 */ diff --git a/apps/vben5/packages/@abp/account/src/utils/auth.ts b/apps/vben5/packages/@abp/account/src/utils/auth.ts index 30a7d616f..39260906b 100644 --- a/apps/vben5/packages/@abp/account/src/utils/auth.ts +++ b/apps/vben5/packages/@abp/account/src/utils/auth.ts @@ -1,8 +1,137 @@ +import type { Logger, UserManagerSettings } from 'oidc-client-ts'; + +import type { + PasswordTokenRequestModel, + PhoneNumberTokenRequest, + QrCodeTokenRequest, +} from '../types/token'; + import { useAppConfig } from '@vben/hooks'; -import { UserManager, WebStorageStateStore } from 'oidc-client-ts'; +import { useRequest } from '@abp/request'; +import { + SigninResponse, + UserManager, + WebStorageStateStore, +} from 'oidc-client-ts'; import SecureLS from 'secure-ls'; +class AbpUserManager extends UserManager { + async _fetchUser(logger: Logger, body: URLSearchParams) { + const { request } = useRequest(); + const url = await this.metadataService.getTokenEndpoint(false); + if (!this.settings.omitScopeWhenRequesting) { + body.set('scope', this.settings.scope); + } + const resp = await request(url, { + data: body, + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + }); + logger.debug('got signin response'); + const response = new SigninResponse(new URLSearchParams()); + Object.assign(response, resp); + const user = await this._buildUser(response); + if (user.profile && user.profile.sub) { + logger.info('success, signed in subject', user.profile.sub); + } else { + logger.info('no subject'); + } + return user; + } + + _writeChangePasswordToken( + params: URLSearchParams, + model: Record, + ) { + if (model.ChangePasswordToken) { + params.set('ChangePasswordToken', model.ChangePasswordToken); + } + if (model.NewPassword) { + params.set('NewPassword', model.NewPassword); + } + } + _writeTenantId(params: URLSearchParams, model: Record) { + if (model.tenantId) { + params.set('tenantId', model.tenantId); + } + } + _writeTwoFactorToken(params: URLSearchParams, model: Record) { + if (model.TwoFactorProvider) { + params.set('TwoFactorProvider', model.TwoFactorProvider); + } + if (model.TwoFactorCode) { + params.set('TwoFactorCode', model.TwoFactorCode); + } + } + _writeUserId(params: URLSearchParams, model: Record) { + if (model.userId) { + params.set('userId', model.userId); + } + } + async signinQrCode(params: QrCodeTokenRequest) { + const logger = this._logger.create('signinQrCode'); + const client_secret = this.settings.client_secret; + if (!client_secret) { + logger.error('A client_id is required'); + throw new Error('A client_id is required'); + } + const body = new URLSearchParams({ + key: params.key, + grant_type: 'qr_code', + client_id: this.settings.client_id, + client_secret, + }); + this._writeUserId(body, params); + this._writeTenantId(body, params); + this._writeTwoFactorToken(body, params); + return await this._fetchUser(logger, body); + } + + override async signinResourceOwnerCredentials( + params: PasswordTokenRequestModel, + ) { + const logger = this._logger.create('signinResourceOwnerCredentials'); + const client_secret = this.settings.client_secret; + if (!client_secret) { + logger.error('A client_id is required'); + throw new Error('A client_id is required'); + } + const body = new URLSearchParams({ + username: params.username, + password: params.password, + grant_type: 'password', + client_id: this.settings.client_id, + client_secret, + }); + this._writeUserId(body, params); + this._writeTwoFactorToken(body, params); + this._writeChangePasswordToken(body, params); + return await this._fetchUser(logger, body); + } + + async signinSmsCode(params: PhoneNumberTokenRequest) { + const logger = this._logger.create('signinSmsCode'); + const client_secret = this.settings.client_secret; + if (!client_secret) { + logger.error('A client_id is required'); + throw new Error('A client_id is required'); + } + const body = new URLSearchParams({ + phone_number: params.phoneNumber, + phone_verify_code: params.code, + grant_type: 'phone_verify', + client_id: this.settings.client_id, + client_secret, + }); + this._writeUserId(body, params); + this._writeTwoFactorToken(body, params); + return await this._fetchUser(logger, body); + } +} + const { authority, audience, clientId, clientSecret, disablePKCE } = useAppConfig(import.meta.env, import.meta.env.PROD); @@ -17,7 +146,7 @@ const ls = new SecureLS({ // @ts-ignore secure-ls does not have a type definition for this metaKey: `${namespace}-secure-oidc`, }); -export const userManager = new UserManager({ +const oidcSettings: UserManagerSettings = { authority, client_id: clientId, client_secret: clientSecret, @@ -50,4 +179,7 @@ export const userManager = new UserManager({ }, }), disablePKCE, -}); +}; +const userManager = new AbpUserManager(oidcSettings); + +export { oidcSettings, userManager };