@axa-fr/oidc-client-service-worker
Version:
OpenID Connect & OAuth authentication service worker
339 lines (293 loc) • 9.02 kB
text/typescript
import { vi } from 'vitest';
import {
AccessTokenPayload,
IdTokenPayload,
Nonce,
OidcConfig,
OidcConfiguration,
OidcServerConfiguration,
Status,
Tokens,
} from '../../types';
const currentTimeUnixSeconds = (): number => {
return new Date().getTime() / 1000;
};
const createToken = (expires: number, issued_at: number): Tokens => {
return {
expiresAt: expires,
issued_at,
expires_in: 60,
id_token: null,
accessTokenPayload: null,
access_token: '',
idTokenPayload: { iss: '', exp: 0, iat: 0, nonce: null },
};
};
class TokenBuilder {
private tokens: Tokens = {
expiresAt: 0,
issued_at: 0,
expires_in: 0,
id_token: null,
accessTokenPayload: null,
access_token: '',
idTokenPayload: { iss: '', exp: 0, iat: 0, nonce: null },
};
public withExpiredToken(): TokenBuilder {
this.withExpiresIn(currentTimeUnixSeconds() - 10);
this.withIssuedAt(currentTimeUnixSeconds() - 60);
return this;
}
public withNonExpiredToken(): TokenBuilder {
this.withExpiresAt(currentTimeUnixSeconds() + 60);
this.withExpiresIn(currentTimeUnixSeconds() + 60);
this.withIssuedAt(currentTimeUnixSeconds() - 60);
return this;
}
public withExpiresAt(expiresAt: number): TokenBuilder {
this.tokens.expiresAt = expiresAt;
return this;
}
public withIssuedAt(issued_at: number | string): TokenBuilder {
this.tokens.issued_at = issued_at;
return this;
}
public withExpiresIn(expires_in: number | string): TokenBuilder {
this.tokens.expires_in = expires_in;
return this;
}
public withIdToken(id_token: string): TokenBuilder {
this.tokens.id_token = id_token;
return this;
}
public withAccessTokenPayload(accessTokenPayload: AccessTokenPayload): TokenBuilder {
this.tokens.accessTokenPayload = accessTokenPayload;
return this;
}
public withAccessToken(access_token: string): TokenBuilder {
this.tokens.access_token = access_token;
return this;
}
public withIdTokenPayload(idTokenPayload: IdTokenPayload): TokenBuilder {
this.tokens.idTokenPayload = idTokenPayload;
return this;
}
public build(): Tokens {
return this.tokens;
}
}
class OidcConfigurationBuilder {
private oidcConfiguration: OidcConfiguration = {
token_renew_mode: 'offline',
demonstrating_proof_of_possession: false,
};
public withTokenRenewMode(token_renew_mode: string): OidcConfigurationBuilder {
this.oidcConfiguration.token_renew_mode = token_renew_mode;
return this;
}
public build(): OidcConfiguration {
return this.oidcConfiguration;
}
}
class OidcConfigBuilder {
private oidcConfig: OidcConfig = {
configurationName: '',
tokens: null,
status: 'NOT_CONNECTED',
state: null,
codeVerifier: null,
nonce: null,
oidcServerConfiguration: null,
oidcConfiguration: undefined,
sessionState: null,
items: undefined,
hideAccessToken: true,
convertAllRequestsToCorsExceptNavigate: false,
setAccessTokenToNavigateRequests: true,
demonstratingProofOfPossessionNonce: null,
demonstratingProofOfPossessionJwkJson: null,
demonstratingProofOfPossessionConfiguration: null,
demonstratingProofOfPossessionOnlyWhenDpopHeaderPresent: false,
allowMultiTabLogin: true,
};
public withTestingDefault(): OidcConfigBuilder {
this.oidcConfig.configurationName = 'test';
this.oidcConfig.tokens = new TokenBuilder().withNonExpiredToken().build();
this.oidcConfig.status = 'NOT_CONNECTED';
this.oidcConfig.state = 'state';
this.oidcConfig.codeVerifier = 'codeVerifier';
this.oidcConfig.nonce = null;
this.oidcConfig.oidcConfiguration = new OidcConfigurationBuilder().build();
this.oidcConfig.oidcServerConfiguration = new OidcServerConfigBuilder()
.withTestingDefault()
.build();
this.oidcConfig.sessionState = null;
this.oidcConfig.items = undefined;
this.oidcConfig.hideAccessToken = true;
return this;
}
public withHideAccessToken(hideAccessToken: boolean): OidcConfigBuilder {
this.oidcConfig.hideAccessToken = hideAccessToken;
return this;
}
public withConfigurationName(configurationName: string): OidcConfigBuilder {
this.oidcConfig.configurationName = configurationName;
return this;
}
public withTokens(tokens: Tokens): OidcConfigBuilder {
this.oidcConfig.tokens = tokens;
return this;
}
public withStatus(status: Status): OidcConfigBuilder {
this.oidcConfig.status = status;
return this;
}
public withState(state: string): OidcConfigBuilder {
this.oidcConfig.state = state;
return this;
}
public withCodeVerifier(codeVerifier: string): OidcConfigBuilder {
this.oidcConfig.codeVerifier = codeVerifier;
return this;
}
public withNonce(nonce: Nonce): OidcConfigBuilder {
this.oidcConfig.nonce = nonce;
return this;
}
public withOidcServerConfiguration(
oidcServerConfiguration: OidcServerConfiguration,
): OidcConfigBuilder {
this.oidcConfig.oidcServerConfiguration = oidcServerConfiguration;
return this;
}
public withOidcConfiguration(oidcConfiguration: OidcConfiguration): OidcConfigBuilder {
this.oidcConfig.oidcConfiguration = oidcConfiguration;
return this;
}
public build() {
return this.oidcConfig;
}
}
class OidcServerConfigBuilder {
private oidcServerConfig: OidcServerConfiguration = {
revocationEndpoint: '',
issuer: '',
authorizationEndpoint: '',
tokenEndpoint: '',
userInfoEndpoint: '',
};
public withTestingDefault(): OidcServerConfigBuilder {
this.oidcServerConfig.revocationEndpoint = 'http://localhost:3000/revocation';
this.oidcServerConfig.issuer = 'http://localhost:3000';
this.oidcServerConfig.authorizationEndpoint = 'http://localhost:3000/authorization';
this.oidcServerConfig.tokenEndpoint = 'http://localhost:3000/token';
this.oidcServerConfig.userInfoEndpoint = 'http://localhost:3000/userinfo';
return this;
}
public withRevocationEndpoint(revocationEndpoint: string): OidcServerConfigBuilder {
this.oidcServerConfig.revocationEndpoint = revocationEndpoint;
return this;
}
public withIssuer(issuer: string): OidcServerConfigBuilder {
this.oidcServerConfig.issuer = issuer;
return this;
}
public withAuthorizationEndpoint(authorizationEndpoint: string): OidcServerConfigBuilder {
this.oidcServerConfig.authorizationEndpoint = authorizationEndpoint;
return this;
}
public withTokenEndpoint(tokenEndpoint: string): OidcServerConfigBuilder {
this.oidcServerConfig.tokenEndpoint = tokenEndpoint;
return this;
}
public withUserInfoEndpoint(userInfoEndpoint: string): OidcServerConfigBuilder {
this.oidcServerConfig.userInfoEndpoint = userInfoEndpoint;
return this;
}
public build(): OidcServerConfiguration {
return this.oidcServerConfig;
}
}
interface TestingResponse extends Response {
bodyContent?: any;
}
class ResponseBuilder {
private response: any = {
status: 200,
body: '',
headers: {},
bodyContent: { issued_at: 343434 },
};
public withStatus(status: number): ResponseBuilder {
this.response.status = status;
return this;
}
public withBody(body: string): ResponseBuilder {
this.response.body = body;
return this;
}
public withHeaders(headers: Headers): ResponseBuilder {
this.response.headers = headers;
return this;
}
/**
* Custom property for Testing setup
* @param body
* @returns
*/
public withBodyContent(body: any): ResponseBuilder {
this.response.bodyContent = body;
return this;
}
public build(): TestingResponse {
return {
...{
status: 200,
headers: {
append: vi.fn(),
delete: vi.fn(),
forEach: vi.fn(),
get: vi.fn(),
has: vi.fn(),
set: vi.fn(),
},
ok: true,
redirected: false,
statusText: '',
type: 'basic',
url: '',
clone: function (): Response {
throw new Error('Function not implemented.');
},
body: null,
bodyUsed: false,
arrayBuffer: function (): Promise<ArrayBuffer> {
throw new Error('Function not implemented.');
},
blob: function (): Promise<Blob> {
throw new Error('Function not implemented.');
},
formData: function (): Promise<FormData> {
throw new Error('Function not implemented.');
},
json: function (): Promise<any> {
return new Promise<any>(resolve => {
resolve(this.bodyContent);
});
},
text: function (): Promise<string> {
throw new Error('Function not implemented.');
},
},
...this.response,
} as TestingResponse;
}
}
export {
createToken,
currentTimeUnixSeconds,
OidcConfigBuilder,
OidcServerConfigBuilder,
ResponseBuilder,
TokenBuilder,
};