Skip to content

Commit

Permalink
add oidc provider data handling in identifo js (#408)
Browse files Browse the repository at this point in the history
Co-authored-by: nikita_kysil <pancxxx2@gmail.com>
  • Loading branch information
mag-nikita-ks and nikita-ks authored Jun 19, 2023
1 parent 3118568 commit 1f7b7ca
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 11 deletions.
19 changes: 18 additions & 1 deletion web_apps_src/identifo.js/dist/identifo.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ interface TokenManager {
saveToken: (token: string, tokenType: TokenType) => boolean;
getToken: (tokenType: TokenType) => string;
deleteToken: (tokenType: TokenType) => void;
saveOIDCProviderData: (data: Record<string, unknown>) => void;
getOIDCProviderData: () => Record<string, string>;
}
declare type IdentifoConfig = {
issuer?: string;
Expand Down Expand Up @@ -76,6 +78,8 @@ declare class TokenService {
validateToken(token: string, audience: string, issuer?: string): Promise<boolean>;
parseJWT(token: string): JWTPayload;
isJWTExpired(token: JWTPayload): boolean;
saveOIDCProviderData(data: Record<string, unknown>): void;
getOIDCProviderData(): Record<string, string>;
saveToken(token: string, type?: TokenType): boolean;
removeToken(type?: TokenType): void;
getToken(type?: TokenType): ClientToken | null;
Expand Down Expand Up @@ -137,6 +141,7 @@ interface LoginResponse {
};
scopes?: string[];
callbackUrl?: string;
provider_data?: OIDCProviderData;
}
interface EnableTFAResponse {
provisioning_uri?: string;
Expand All @@ -147,6 +152,13 @@ interface TokenResponse {
access_token?: string;
refresh_token?: string;
}
interface OIDCProviderData {
token_type?: string;
access_token?: string;
refresh_token?: string;
expiry?: string;
[x: string]: string | undefined;
}
interface AppSettingsResponse {
anonymousResitrationAllowed: boolean;
active: boolean;
Expand Down Expand Up @@ -239,6 +251,7 @@ declare class API {
scopes: string[];
}): Promise<LoginResponse>;
invite(email: string, role: string, callbackUrl: string): Promise<InviteResponse>;
handleOIDCResponse<T extends LoginResponse>(response: T): T;
storeToken<T extends TokenResponse>(response: T): T;
}

Expand All @@ -259,6 +272,7 @@ declare class IdentifoAuth {
handleAuthentication(): Promise<boolean>;
private getTokenFromUrl;
getToken(): Promise<ClientToken | null>;
getOIDCProviderData(): Record<string, string>;
renewSession(): Promise<string>;
private renewSessionWithToken;
}
Expand All @@ -275,11 +289,14 @@ declare class StorageManager implements TokenManager {
storageType: 'localStorage' | 'sessionStorage';
access: string;
refresh: string;
oidcProviderDataKey: string;
isAccessible: boolean;
constructor(storageType: 'localStorage' | 'sessionStorage', accessKey?: string, refreshKey?: string);
saveToken(token: string, tokenType: TokenType): boolean;
getToken(tokenType: TokenType): string;
deleteToken(tokenType: TokenType): void;
getOIDCProviderData(): Record<string, string>;
saveOIDCProviderData(data?: Record<string, unknown>): void;
}

declare class LocalStorage extends StorageManager {
Expand Down Expand Up @@ -501,4 +518,4 @@ declare class CDK {
private getLoginTypes;
}

export { APIErrorCodes, ApiError, ApiRequestError, AppSettingsResponse, CDK, ClientToken, CookieStorage as CookieStorageManager, EnableTFAResponse, FederatedLoginProvider, IdentifoAuth, IdentifoConfig, InviteResponse, JWTPayload, LocalStorage as LocalStorageManager, LoginResponse, LoginTypes, Routes, ServerSettingsLoginTypes, SessionStorage as SessionStorageManager, State, StateCallback, StateError, StateLoading, StateLogin, StateLoginOidc, StateLoginPhone, StateLoginPhoneVerify, StateLogout, StatePasswordForgot, StatePasswordForgotSuccess, StatePasswordForgotTFASelect, StatePasswordForgotTFAVerify, StatePasswordReset, StateRegister, StateTFASetupApp, StateTFASetupEmail, StateTFASetupSMS, StateTFASetupSelect, StateTFAVerifyApp, StateTFAVerifyEmailSms, StateTFAVerifySelect, StateWithError, States, SuccessResponse, TFALoginVerifyRoutes, TFARequiredRespopnse, TFAResetVerifyRoutes, TFASetupRoutes, TFAStatus, TFAType, TokenManager, TokenResponse, TokenType, UpdateUser, UrlBuilderInit, UrlFlows, User, typeToPasswordForgotTFAVerifyRoute, typeToSetupRoute, typeToTFAVerifyRoute };
export { APIErrorCodes, ApiError, ApiRequestError, AppSettingsResponse, CDK, ClientToken, CookieStorage as CookieStorageManager, EnableTFAResponse, FederatedLoginProvider, IdentifoAuth, IdentifoConfig, InviteResponse, JWTPayload, LocalStorage as LocalStorageManager, LoginResponse, LoginTypes, OIDCProviderData, Routes, ServerSettingsLoginTypes, SessionStorage as SessionStorageManager, State, StateCallback, StateError, StateLoading, StateLogin, StateLoginOidc, StateLoginPhone, StateLoginPhoneVerify, StateLogout, StatePasswordForgot, StatePasswordForgotSuccess, StatePasswordForgotTFASelect, StatePasswordForgotTFAVerify, StatePasswordReset, StateRegister, StateTFASetupApp, StateTFASetupEmail, StateTFASetupSMS, StateTFASetupSelect, StateTFAVerifyApp, StateTFAVerifyEmailSms, StateTFAVerifySelect, StateWithError, States, SuccessResponse, TFALoginVerifyRoutes, TFARequiredRespopnse, TFAResetVerifyRoutes, TFASetupRoutes, TFAStatus, TFAType, TokenManager, TokenResponse, TokenType, UpdateUser, UrlBuilderInit, UrlFlows, User, typeToPasswordForgotTFAVerifyRoute, typeToSetupRoute, typeToTFAVerifyRoute };
30 changes: 29 additions & 1 deletion web_apps_src/identifo.js/dist/identifo.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web_apps_src/identifo.js/dist/identifo.js.map

Large diffs are not rendered by default.

30 changes: 29 additions & 1 deletion web_apps_src/identifo.js/dist/identifo.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ class API {
oidcVerify(data) {
return __async$3(this, null, function* () {
const url = `/auth/federated/oidc/complete?appId=${this.appId}&state=${data.state}&code=${data.code}`;
return this.post(url, { scopes: data.scopes }, { credentials: "include" }).then((r) => this.storeToken(r));
return this.post(url, { scopes: data.scopes }, { credentials: "include" }).then((r) => this.storeToken(r)).then((r) => this.handleOIDCResponse(r));
});
}
invite(email, role, callbackUrl) {
Expand All @@ -331,6 +331,12 @@ class API {
});
});
}
handleOIDCResponse(response) {
if (response.provider_data) {
this.tokenService.saveOIDCProviderData(response.provider_data);
}
return response;
}
storeToken(response) {
if (response.access_token) {
this.tokenService.saveToken(response.access_token, "access");
Expand Down Expand Up @@ -367,6 +373,7 @@ class StorageManager {
this.storageType = "localStorage";
this.access = `${this.preffix}access_token`;
this.refresh = `${this.preffix}refresh_token`;
this.oidcProviderDataKey = `${this.preffix}oidc_provider_data`;
this.isAccessible = true;
this.access = accessKey ? this.preffix + accessKey : this.access;
this.refresh = refreshKey ? this.preffix + refreshKey : this.refresh;
Expand All @@ -386,6 +393,18 @@ class StorageManager {
deleteToken(tokenType) {
window[this.storageType].removeItem(this[tokenType]);
}
getOIDCProviderData() {
var _a;
try {
return JSON.parse((_a = window[this.storageType].getItem(this.oidcProviderDataKey)) != null ? _a : "{}");
} catch (error) {
console.error(error);
return {};
}
}
saveOIDCProviderData(data = {}) {
window[this.storageType].setItem(this.oidcProviderDataKey, JSON.stringify(data));
}
}

class LocalStorage extends StorageManager {
Expand Down Expand Up @@ -467,6 +486,12 @@ class TokenService {
}
return false;
}
saveOIDCProviderData(data) {
this.tokenManager.saveOIDCProviderData(data);
}
getOIDCProviderData() {
return this.tokenManager.getOIDCProviderData();
}
saveToken(token, type = "access") {
if (type === "access") {
this.isAuth = true;
Expand Down Expand Up @@ -661,6 +686,9 @@ class IdentifoAuth {
return Promise.resolve(null);
});
}
getOIDCProviderData() {
return this.tokenService.getOIDCProviderData();
}
renewSession() {
return __async$1(this, null, function* () {
try {
Expand Down
2 changes: 1 addition & 1 deletion web_apps_src/identifo.js/dist/identifo.mjs.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions web_apps_src/identifo.js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web_apps_src/identifo.js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@identifo/identifo-auth-js",
"version": "3.3.9",
"version": "3.4.6",
"description": "Library for web-auth through Identifo",
"main": "./dist/identifo.js",
"module": "./dist/identifo.mjs",
Expand Down
4 changes: 4 additions & 0 deletions web_apps_src/identifo.js/src/IdentifoAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class IdentifoAuth {
return Promise.resolve(null);
}

getOIDCProviderData(): Record<string, string> {
return this.tokenService.getOIDCProviderData();
}

async renewSession(): Promise<string> {
try {
const { access, refresh } = await this.renewSessionWithToken();
Expand Down
13 changes: 10 additions & 3 deletions web_apps_src/identifo.js/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,9 @@ export class API {

async oidcVerify(data: { state: string; code: string; scopes: string[] }): Promise<LoginResponse> {
const url = `/auth/federated/oidc/complete?appId=${this.appId}&state=${data.state}&code=${data.code}`;
return this.post<LoginResponse>(url, { scopes: data.scopes }, { credentials: 'include' }).then((r) =>
this.storeToken(r),
);
return this.post<LoginResponse>(url, { scopes: data.scopes }, { credentials: 'include' })
.then((r) => this.storeToken(r))
.then((r) => this.handleOIDCResponse(r));
}

async invite(email: string, role: string, callbackUrl: string): Promise<InviteResponse> {
Expand All @@ -324,6 +324,13 @@ export class API {
);
}

handleOIDCResponse<T extends LoginResponse>(response: T): T {
if (response.provider_data) {
this.tokenService.saveOIDCProviderData(response.provider_data);
}
return response;
}

storeToken<T extends TokenResponse>(response: T): T {
if (response.access_token) {
this.tokenService.saveToken(response.access_token, 'access');
Expand Down
8 changes: 8 additions & 0 deletions web_apps_src/identifo.js/src/api/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface LoginResponse {
};
scopes?: string[];
callbackUrl?: string;
provider_data?: OIDCProviderData;
}
export interface EnableTFAResponse {
provisioning_uri?: string;
Expand All @@ -75,6 +76,13 @@ export interface TokenResponse {
access_token?: string;
refresh_token?: string;
}
export interface OIDCProviderData {
token_type?: string;
access_token?: string;
refresh_token?: string;
expiry?: string;
[x: string]: string | undefined;
}
export interface AppSettingsResponse {
anonymousResitrationAllowed: boolean;
active: boolean;
Expand Down
15 changes: 15 additions & 0 deletions web_apps_src/identifo.js/src/store-manager/storage-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class StorageManager implements TokenManager {

refresh = `${this.preffix}refresh_token`;

oidcProviderDataKey = `${this.preffix}oidc_provider_data`;

isAccessible = true;

constructor(storageType: 'localStorage' | 'sessionStorage', accessKey?: string, refreshKey?: string) {
Expand All @@ -32,6 +34,19 @@ class StorageManager implements TokenManager {
deleteToken(tokenType: TokenType): void {
window[this.storageType].removeItem(this[tokenType]);
}

getOIDCProviderData(): Record<string, string> {
try {
return JSON.parse(window[this.storageType].getItem(this.oidcProviderDataKey) ?? '{}');
} catch (error) {
console.error(error);
return {};
}
}

saveOIDCProviderData(data: Record<string, unknown> = {}): void {
window[this.storageType].setItem(this.oidcProviderDataKey, JSON.stringify(data));
}
}

export default StorageManager;
8 changes: 8 additions & 0 deletions web_apps_src/identifo.js/src/tokenService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ class TokenService {
return false;
}

saveOIDCProviderData(data: Record<string, unknown>) {
this.tokenManager.saveOIDCProviderData(data);
}

getOIDCProviderData(): Record<string, string> {
return this.tokenManager.getOIDCProviderData();
}

saveToken(token: string, type: TokenType = 'access'): boolean {
if (type === 'access') {
this.isAuth = true;
Expand Down
2 changes: 2 additions & 0 deletions web_apps_src/identifo.js/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface TokenManager {
saveToken: (token: string, tokenType: TokenType) => boolean;
getToken: (tokenType: TokenType) => string;
deleteToken: (tokenType: TokenType) => void;
saveOIDCProviderData: (data: Record<string, unknown>) => void;
getOIDCProviderData: () => Record<string, string>;
}

export type IdentifoConfig = {
Expand Down

0 comments on commit 1f7b7ca

Please sign in to comment.