Skip to content

Instantly share code, notes, and snippets.

@robinmanuelthiel
Last active April 6, 2021 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinmanuelthiel/642f3034d06bf0d8a08aef0a38ff0c02 to your computer and use it in GitHub Desktop.
Save robinmanuelthiel/642f3034d06bf0d8a08aef0a38ff0c02 to your computer and use it in GitHub Desktop.
export default class CrytoHelpers {
static generateRandomString(): string {
var array = new Uint32Array(64);
window.crypto.getRandomValues(array);
return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
}
static async pkceChallengeFromVerifierAsync(v: string): Promise<string> {
const hashed = await this.sha256(v);
return this.base64urlencode(hashed);
}
private static async sha256(plain: string): Promise<ArrayBuffer> {
const encoder = new TextEncoder();
const data = encoder.encode(plain);
return await window.crypto.subtle.digest('SHA-256', data);
}
// Base64-urlencodes the input string
private static base64urlencode(str: ArrayBuffer): string {
// Convert the ArrayBuffer to string using Uint8 array to convert to what btoa accepts.
// btoa accepts chars only within ascii 0-255 and base64 encodes them.
// Then convert the base64 encoded to base64url encoded
// (replace + with -, replace / with _, trim trailing =)
return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
}
async refreshAccessTokenAsync(): Promise<TokenResponse> {
const refreshToken = localStorage.getItem(Conventions.refreshTokenKey);
if (!refreshToken) {
throw new Error(`No refresh token found in local storage key '${Conventions.refreshTokenKey}'.`);
}
const tokenRequest: TokenRequest = {
refreshToken: refreshToken,
grantType: 'refresh_token', // TODO: Make enum
clientId: this.clientId
};
const url = `${this.wemogyIdentityPublicUrl}/oauth/token`;
const response = await this.httpClient.post<TokenResponse>(url, tokenRequest);
const tokenResponse = Object.setPrototypeOf(response.data, new TokenResponse()) as TokenResponse;
const now = new Date();
now.setSeconds(now.getSeconds() + tokenResponse.expiresIn);
localStorage.setItem(Conventions.accessTokenKey, tokenResponse.accessToken);
localStorage.setItem(Conventions.idTokenKey, tokenResponse.idToken);
localStorage.setItem(Conventions.refreshTokenKey, tokenResponse.refreshToken);
localStorage.setItem(Conventions.expiresAtKey, now.getTime().toString());
return tokenResponse;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment