Skip to content

Commit

Permalink
feat(sdk-core): migrate middleware auth plugin to ES6 crypto base
Browse files Browse the repository at this point in the history
  • Loading branch information
kpanot committed Aug 29, 2024
1 parent d4cb35e commit 4cdcc7a
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 18 deletions.
1 change: 1 addition & 0 deletions packages/@ama-sdk/core/src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from './fetch-cache/index';
export * from './fetch-credentials/index';
export * from './json-token/index';
export * from './keepalive/index';
export * from './mgw-mdw-auth/index';
export * from './mock-intercept/index';
export * from './perf-metric/index';
export * from './pii-tokenizer/index';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { v4 } from 'uuid';
import { base64EncodeUrl, createBase64Encoder, createBase64UrlEncoder } from '../../utils/json-token';
import { PluginRunner, RequestOptions, RequestPlugin } from '../core';
import type { createHmac as createHmacType, webcrypto } from 'node:crypto';


/**
Expand All @@ -10,9 +9,7 @@ import type { createHmac as createHmacType, webcrypto } from 'node:crypto';
*/
export async function sha256(value: string) {
const utf8 = new TextEncoder().encode(value);
// TODO: Use new Ecmascript crypto feature to avoid "require" call (issue #2110)
// eslint-disable-next-line @typescript-eslint/no-require-imports
const hashBuffer = await (globalThis.crypto || (require('node:crypto').webcrypto as typeof webcrypto)).subtle.digest('SHA-256', utf8);
const hashBuffer = await crypto.subtle.digest('SHA-256', utf8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((bytes) => bytes.toString(16).padStart(2, '0'))
Expand All @@ -27,17 +24,14 @@ export async function sha256(value: string) {
* @param value Value to hash
* @param secretKey Secret cryptographic key
*/
export function hmacSHA256(value: string, secretKey: string) {
try {
// TODO: Use new Ecmascript crypto feature to avoid "require" call (issue #2110)
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { createHmac }: { createHmac: typeof createHmacType } = require('node:crypto');
return createHmac('sha256', secretKey)
.update(value, 'latin1')
.digest('base64');
} catch (err) {
throw new Error('Crypto module is not available.');
}
export async function hmacSHA256(value: string, secretKey: string) {
const enc = new TextEncoder();
const algorithm = { name: 'HMAC', hash: 'SHA-256' };

const key = await crypto.subtle.importKey('raw', enc.encode(secretKey), algorithm, false, ['sign', 'verify']);
const signature = await crypto.subtle.sign(algorithm.name, key, enc.encode(value));
const digest = btoa(String.fromCharCode(...new Uint8Array(signature)));
return digest;
}

/**
Expand Down Expand Up @@ -230,9 +224,9 @@ export class MicroGatewayMiddlewareAuthenticationRequest implements RequestPlugi
* @param payload JWT payload
* @param secretKey secret key used to generate the signature
*/
private sign(payload: JsonTokenPayload, secretKey: string) {
private async sign(payload: JsonTokenPayload, secretKey: string) {
const message = `${this.base64UrlEncoder(JSON.stringify(jwsHeader))}.${this.base64UrlEncoder(JSON.stringify(payload))}`;
const signature = hmacSHA256(message, secretKey);
const signature = await hmacSHA256(message, secretKey);
const encodedSignature = base64EncodeUrl(signature);
return `${message}.${encodedSignature}`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe('JSON auth token request plugin', () => {
const secretKey = await sha256(jsonAuthTokenOptions.apiKey + (await sha256(jsonAuthTokenOptions.secret + payload.jti + payload.iat + routePath)));
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
const message = `${base64UrlEncoder(JSON.stringify(header))}.${base64UrlEncoder(JSON.stringify(payload))}`;
const signCheck = base64EncodeUrl(hmacSHA256(message, secretKey));
const signCheck = base64EncodeUrl(await hmacSHA256(message, secretKey));

expect(signature).toEqual(signCheck);
});
Expand Down

0 comments on commit 4cdcc7a

Please sign in to comment.