1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-23 11:43:46 +00:00

Auth/ps 2298 reorg auth (#4564)

* Move auth service factories to Auth team

* Move authentication componenets to Auth team

* Move auth guard services to Auth team

* Move Duo content script to Auth team

* Move auth CLI commands to Auth team

* Move Desktop Account components to Auth Team

* Move Desktop guards to Auth team

* Move two-factor provider images to Auth team

* Move web Accounts components to Auth Team

* Move web settings components to Auth Team

* Move web two factor images to Auth Team

* Fix missed import changes for Auth Team

* Fix Linting errors

* Fix missed CLI imports

* Fix missed Desktop imports

* Revert images move

* Fix missed imports in Web

* Move angular lib components to Auth Team

* Move angular auth guards to Auth team

* Move strategy specs to Auth team

* Update .eslintignore for new paths

* Move lib common abstractions to Auth team

* Move services to Auth team

* Move common lib enums to Auth team

* Move webauthn iframe to Auth team

* Move lib common domain models to Auth team

* Move common lib requests to Auth team

* Move response models to Auth team

* Clean up whitelist

* Move bit web components to Auth team

* Move SSO and SCIM files to Auth team

* Revert move SCIM to Auth team

SCIM belongs to Admin Console team

* Move captcha to Auth team

* Move key connector to Auth team

* Move emergency access to auth team

* Delete extra file

* linter fixes

* Move kdf config to auth team

* Fix whitelist

* Fix duo autoformat

* Complete two factor provider request move

* Fix whitelist names

* Fix login capitalization

* Revert hint dependency reordering

* Revert hint dependency reordering

* Revert hint component

This components is being picked up as a move between clients

* Move web hint component to Auth team

* Move new files to auth team

* Fix desktop build

* Fix browser build
This commit is contained in:
Matt Gibson
2023-02-06 16:53:37 -05:00
committed by GitHub
parent 084c89107e
commit cf972e784c
377 changed files with 1030 additions and 998 deletions

View File

@@ -0,0 +1,181 @@
import { StateService } from "../../abstractions/state.service";
import { Utils } from "../../misc/utils";
import { TokenService as TokenServiceAbstraction } from "../abstractions/token.service";
import { IdentityTokenResponse } from "../models/response/identity-token.response";
export class TokenService implements TokenServiceAbstraction {
static decodeToken(token: string): Promise<any> {
if (token == null) {
throw new Error("Token not provided.");
}
const parts = token.split(".");
if (parts.length !== 3) {
throw new Error("JWT must have 3 parts");
}
const decoded = Utils.fromUrlB64ToUtf8(parts[1]);
if (decoded == null) {
throw new Error("Cannot decode the token");
}
const decodedToken = JSON.parse(decoded);
return decodedToken;
}
constructor(private stateService: StateService) {}
async setTokens(
accessToken: string,
refreshToken: string,
clientIdClientSecret: [string, string]
): Promise<any> {
await this.setToken(accessToken);
await this.setRefreshToken(refreshToken);
if (clientIdClientSecret != null) {
await this.setClientId(clientIdClientSecret[0]);
await this.setClientSecret(clientIdClientSecret[1]);
}
}
async setClientId(clientId: string): Promise<any> {
return await this.stateService.setApiKeyClientId(clientId);
}
async getClientId(): Promise<string> {
return await this.stateService.getApiKeyClientId();
}
async setClientSecret(clientSecret: string): Promise<any> {
return await this.stateService.setApiKeyClientSecret(clientSecret);
}
async getClientSecret(): Promise<string> {
return await this.stateService.getApiKeyClientSecret();
}
async setToken(token: string): Promise<void> {
await this.stateService.setAccessToken(token);
}
async getToken(): Promise<string> {
return await this.stateService.getAccessToken();
}
async setRefreshToken(refreshToken: string): Promise<any> {
return await this.stateService.setRefreshToken(refreshToken);
}
async getRefreshToken(): Promise<string> {
return await this.stateService.getRefreshToken();
}
async setTwoFactorToken(tokenResponse: IdentityTokenResponse): Promise<any> {
return await this.stateService.setTwoFactorToken(tokenResponse.twoFactorToken);
}
async getTwoFactorToken(): Promise<string> {
return await this.stateService.getTwoFactorToken();
}
async clearTwoFactorToken(): Promise<any> {
return await this.stateService.setTwoFactorToken(null);
}
async clearToken(userId?: string): Promise<any> {
await this.stateService.setAccessToken(null, { userId: userId });
await this.stateService.setRefreshToken(null, { userId: userId });
await this.stateService.setApiKeyClientId(null, { userId: userId });
await this.stateService.setApiKeyClientSecret(null, { userId: userId });
}
// jwthelper methods
// ref https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwt.js
async decodeToken(token?: string): Promise<any> {
token = token ?? (await this.stateService.getAccessToken());
if (token == null) {
throw new Error("Token not found.");
}
return TokenService.decodeToken(token);
}
async getTokenExpirationDate(): Promise<Date> {
const decoded = await this.decodeToken();
if (typeof decoded.exp === "undefined") {
return null;
}
const d = new Date(0); // The 0 here is the key, which sets the date to the epoch
d.setUTCSeconds(decoded.exp);
return d;
}
async tokenSecondsRemaining(offsetSeconds = 0): Promise<number> {
const d = await this.getTokenExpirationDate();
if (d == null) {
return 0;
}
const msRemaining = d.valueOf() - (new Date().valueOf() + offsetSeconds * 1000);
return Math.round(msRemaining / 1000);
}
async tokenNeedsRefresh(minutes = 5): Promise<boolean> {
const sRemaining = await this.tokenSecondsRemaining();
return sRemaining < 60 * minutes;
}
async getUserId(): Promise<string> {
const decoded = await this.decodeToken();
if (typeof decoded.sub === "undefined") {
throw new Error("No user id found");
}
return decoded.sub as string;
}
async getEmail(): Promise<string> {
const decoded = await this.decodeToken();
if (typeof decoded.email === "undefined") {
throw new Error("No email found");
}
return decoded.email as string;
}
async getEmailVerified(): Promise<boolean> {
const decoded = await this.decodeToken();
if (typeof decoded.email_verified === "undefined") {
throw new Error("No email verification found");
}
return decoded.email_verified as boolean;
}
async getName(): Promise<string> {
const decoded = await this.decodeToken();
if (typeof decoded.name === "undefined") {
return null;
}
return decoded.name as string;
}
async getIssuer(): Promise<string> {
const decoded = await this.decodeToken();
if (typeof decoded.iss === "undefined") {
throw new Error("No issuer found");
}
return decoded.iss as string;
}
async getIsExternal(): Promise<boolean> {
const decoded = await this.decodeToken();
return Array.isArray(decoded.amr) && decoded.amr.includes("external");
}
}