@turnkey/api-key-stamper
Version:
API key stamper for @turnkey/http
107 lines (103 loc) • 4.08 kB
JavaScript
;
var encoding = require('@turnkey/encoding');
var crypto$1 = require('@turnkey/crypto');
var elliptic_curves = require('./tink/elliptic_curves.js');
/// <reference lib="dom" />
// Header name for an API key stamp
const stampHeaderName = "X-Stamp";
exports.SignatureFormat = void 0;
(function (SignatureFormat) {
SignatureFormat["Der"] = "der";
SignatureFormat["Raw"] = "raw";
})(exports.SignatureFormat || (exports.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 Promise.resolve().then(function () { return require('./webcrypto.js'); })).signWithApiKey(input);
case "node":
return (await Promise.resolve().then(function () { return require('./nodecrypto.js'); })).signWithApiKey(input);
case "purejs":
return (await Promise.resolve().then(function () { return require('./purejs.js'); })).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: encoding.stringToBase64urlString(JSON.stringify(stamp)),
};
}
async sign(payload, format) {
switch (format) {
case exports.SignatureFormat.Raw: {
const derSignature = await signWithApiKey({
publicKey: this.apiPublicKey,
privateKey: this.apiPrivateKey,
content: payload,
}, this.runtimeOverride);
const raw = crypto$1.fromDerSignature(derSignature);
return encoding.uint8ArrayToHexString(raw);
}
case exports.SignatureFormat.Der: {
return signWithApiKey({
publicKey: this.apiPublicKey,
privateKey: this.apiPrivateKey,
content: payload,
}, this.runtimeOverride);
}
default:
throw new Error(`Unsupported signature format: ${format}`);
}
}
}
exports.pointDecode = elliptic_curves.pointDecode;
exports.ApiKeyStamper = ApiKeyStamper;
exports.signWithApiKey = signWithApiKey;
//# sourceMappingURL=index.js.map