@turnkey/api-key-stamper
Version:
API key stamper for @turnkey/http
103 lines (100 loc) • 3.83 kB
JavaScript
import { stringToBase64urlString, uint8ArrayToHexString } from '@turnkey/encoding';
import { fromDerSignature } from '@turnkey/crypto';
export { pointDecode } from './tink/elliptic_curves.mjs';
/// <reference lib="dom" />
// Header name for an API key stamp
const stampHeaderName = "X-Stamp";
var SignatureFormat;
(function (SignatureFormat) {
SignatureFormat["Der"] = "der";
SignatureFormat["Raw"] = "raw";
})(SignatureFormat || (SignatureFormat = {}));
// `window.document` ensures that we're in a browser context
// and `crypto.subtle` ensures that it supports the web crypto APIs
// Inspired by https://github.com/flexdinesh/browser-or-node/blob/master/src/index.ts
const isCryptoEnabledBrowser = typeof window !== "undefined" &&
typeof window.document !== "undefined" &&
typeof crypto !== "undefined" &&
typeof crypto.subtle !== "undefined";
// We check `process.versions.node`
// Taken from https://github.com/flexdinesh/browser-or-node/blob/master/src/index.ts
const isNode = typeof process !== "undefined" &&
process.versions != null &&
process.versions.node != null;
const detectRuntime = () => {
if (isCryptoEnabledBrowser) {
return "browser";
}
if (isNode) {
return "node";
}
// If we don't have NodeJS or web crypto at our disposal, default to pure JS implementation
// This is the case for old browsers and react native environments
return "purejs";
};
/**
* Signature function abstracting the differences between NodeJS and web environments for signing with API keys.
*/
const signWithApiKey = async (input, runtimeOverride) => {
const runtime = runtimeOverride ?? detectRuntime();
switch (runtime) {
case "browser":
return (await import('./webcrypto.mjs')).signWithApiKey(input);
case "node":
return (await import('./nodecrypto.mjs')).signWithApiKey(input);
case "purejs":
return (await import('./purejs.mjs')).signWithApiKey(input);
default:
throw new Error(`Unsupported runtime: ${runtime}`);
}
};
/**
* Stamper to use with `@turnkey/http`'s `TurnkeyClient`
*/
class ApiKeyStamper {
constructor(config) {
this.apiPublicKey = config.apiPublicKey;
this.apiPrivateKey = config.apiPrivateKey;
this.runtimeOverride = config.runtimeOverride;
}
async stamp(payload) {
const signature = await signWithApiKey({
publicKey: this.apiPublicKey,
privateKey: this.apiPrivateKey,
content: payload,
}, this.runtimeOverride);
const stamp = {
publicKey: this.apiPublicKey,
scheme: "SIGNATURE_SCHEME_TK_API_P256",
signature,
};
return {
stampHeaderName,
stampHeaderValue: stringToBase64urlString(JSON.stringify(stamp)),
};
}
async sign(payload, format) {
switch (format) {
case SignatureFormat.Raw: {
const derSignature = await signWithApiKey({
publicKey: this.apiPublicKey,
privateKey: this.apiPrivateKey,
content: payload,
}, this.runtimeOverride);
const raw = fromDerSignature(derSignature);
return uint8ArrayToHexString(raw);
}
case SignatureFormat.Der: {
return signWithApiKey({
publicKey: this.apiPublicKey,
privateKey: this.apiPrivateKey,
content: payload,
}, this.runtimeOverride);
}
default:
throw new Error(`Unsupported signature format: ${format}`);
}
}
}
export { ApiKeyStamper, SignatureFormat, signWithApiKey };
//# sourceMappingURL=index.mjs.map