UNPKG

@aws-amplify/auth

Version:
167 lines (164 loc) 7.65 kB
import { decodeJWT, assertTokenProviderConfig } from '@aws-amplify/core/internals/utils'; import { AuthError } from '../../../errors/AuthError.mjs'; import { AuthTokenStorageKeys } from './types.mjs'; import { assert, TokenProviderErrorCode } from './errorHelpers.mjs'; import { AUTH_KEY_PREFIX } from './constants.mjs'; class DefaultTokenStore { getKeyValueStorage() { if (!this.keyValueStorage) { throw new AuthError({ name: 'KeyValueStorageNotFoundException', message: 'KeyValueStorage was not found in TokenStore', }); } return this.keyValueStorage; } setKeyValueStorage(keyValueStorage) { this.keyValueStorage = keyValueStorage; } setAuthConfig(authConfig) { this.authConfig = authConfig; } async loadTokens() { // TODO(v6): migration logic should be here // Reading V5 tokens old format try { const authKeys = await this.getAuthKeys(); const accessTokenString = await this.getKeyValueStorage().getItem(authKeys.accessToken); if (!accessTokenString) { throw new AuthError({ name: 'NoSessionFoundException', message: 'Auth session was not found. Make sure to call signIn.', }); } const accessToken = decodeJWT(accessTokenString); const itString = await this.getKeyValueStorage().getItem(authKeys.idToken); const idToken = itString ? decodeJWT(itString) : undefined; const refreshToken = (await this.getKeyValueStorage().getItem(authKeys.refreshToken)) ?? undefined; const clockDriftString = (await this.getKeyValueStorage().getItem(authKeys.clockDrift)) ?? '0'; const clockDrift = Number.parseInt(clockDriftString); const signInDetails = await this.getKeyValueStorage().getItem(authKeys.signInDetails); const tokens = { accessToken, idToken, refreshToken, deviceMetadata: (await this.getDeviceMetadata()) ?? undefined, clockDrift, username: await this.getLastAuthUser(), }; if (signInDetails) { tokens.signInDetails = JSON.parse(signInDetails); } return tokens; } catch (err) { return null; } } async storeTokens(tokens) { assert(tokens !== undefined, TokenProviderErrorCode.InvalidAuthTokens); const lastAuthUser = tokens.username; await this.getKeyValueStorage().setItem(this.getLastAuthUserKey(), lastAuthUser); const authKeys = await this.getAuthKeys(); await this.getKeyValueStorage().setItem(authKeys.accessToken, tokens.accessToken.toString()); if (tokens.idToken) { await this.getKeyValueStorage().setItem(authKeys.idToken, tokens.idToken.toString()); } else { await this.getKeyValueStorage().removeItem(authKeys.idToken); } if (tokens.refreshToken) { await this.getKeyValueStorage().setItem(authKeys.refreshToken, tokens.refreshToken); } else { await this.getKeyValueStorage().removeItem(authKeys.refreshToken); } if (tokens.deviceMetadata) { if (tokens.deviceMetadata.deviceKey) { await this.getKeyValueStorage().setItem(authKeys.deviceKey, tokens.deviceMetadata.deviceKey); } if (tokens.deviceMetadata.deviceGroupKey) { await this.getKeyValueStorage().setItem(authKeys.deviceGroupKey, tokens.deviceMetadata.deviceGroupKey); } await this.getKeyValueStorage().setItem(authKeys.randomPasswordKey, tokens.deviceMetadata.randomPassword); } if (tokens.signInDetails) { await this.getKeyValueStorage().setItem(authKeys.signInDetails, JSON.stringify(tokens.signInDetails)); } else { await this.getKeyValueStorage().removeItem(authKeys.signInDetails); } await this.getKeyValueStorage().setItem(authKeys.clockDrift, `${tokens.clockDrift}`); } async clearTokens() { const authKeys = await this.getAuthKeys(); // Not calling clear because it can remove data that is not managed by AuthTokenStore await Promise.all([ this.getKeyValueStorage().removeItem(authKeys.accessToken), this.getKeyValueStorage().removeItem(authKeys.idToken), this.getKeyValueStorage().removeItem(authKeys.clockDrift), this.getKeyValueStorage().removeItem(authKeys.refreshToken), this.getKeyValueStorage().removeItem(authKeys.signInDetails), this.getKeyValueStorage().removeItem(this.getLastAuthUserKey()), this.getKeyValueStorage().removeItem(authKeys.oauthMetadata), ]); } async getDeviceMetadata(username) { const authKeys = await this.getAuthKeys(username); const deviceKey = await this.getKeyValueStorage().getItem(authKeys.deviceKey); const deviceGroupKey = await this.getKeyValueStorage().getItem(authKeys.deviceGroupKey); const randomPassword = await this.getKeyValueStorage().getItem(authKeys.randomPasswordKey); return randomPassword && deviceGroupKey && deviceKey ? { deviceKey, deviceGroupKey, randomPassword, } : null; } async clearDeviceMetadata(username) { const authKeys = await this.getAuthKeys(username); await Promise.all([ this.getKeyValueStorage().removeItem(authKeys.deviceKey), this.getKeyValueStorage().removeItem(authKeys.deviceGroupKey), this.getKeyValueStorage().removeItem(authKeys.randomPasswordKey), ]); } async getAuthKeys(username) { assertTokenProviderConfig(this.authConfig?.Cognito); const lastAuthUser = username ?? (await this.getLastAuthUser()); return createKeysForAuthStorage(AUTH_KEY_PREFIX, `${this.authConfig.Cognito.userPoolClientId}.${lastAuthUser}`); } getLastAuthUserKey() { assertTokenProviderConfig(this.authConfig?.Cognito); const identifier = this.authConfig.Cognito.userPoolClientId; return `${AUTH_KEY_PREFIX}.${identifier}.LastAuthUser`; } async getLastAuthUser() { const lastAuthUser = (await this.getKeyValueStorage().getItem(this.getLastAuthUserKey())) ?? 'username'; return lastAuthUser; } async setOAuthMetadata(metadata) { const { oauthMetadata: oauthMetadataKey } = await this.getAuthKeys(); await this.getKeyValueStorage().setItem(oauthMetadataKey, JSON.stringify(metadata)); } async getOAuthMetadata() { const { oauthMetadata: oauthMetadataKey } = await this.getAuthKeys(); const oauthMetadata = await this.getKeyValueStorage().getItem(oauthMetadataKey); return oauthMetadata && JSON.parse(oauthMetadata); } } const createKeysForAuthStorage = (provider, identifier) => { return getAuthStorageKeys(AuthTokenStorageKeys)(`${provider}`, identifier); }; function getAuthStorageKeys(authKeys) { const keys = Object.values({ ...authKeys }); return (prefix, identifier) => keys.reduce((acc, authKey) => ({ ...acc, [authKey]: `${prefix}.${identifier}.${authKey}`, }), {}); } export { DefaultTokenStore, createKeysForAuthStorage, getAuthStorageKeys }; //# sourceMappingURL=TokenStore.mjs.map