UNPKG

@cfworker/cosmos

Version:

Azure Cosmos DB client for Cloudflare Workers and service workers

50 lines (49 loc) 2.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Signer = void 0; exports.getSigner = getSigner; const rfc4648_1 = require("rfc4648"); class Signer { masterkey; encoder = new TextEncoder(); constructor(masterkey) { const promiseLike = crypto.subtle.importKey('raw', rfc4648_1.base64.parse(masterkey), { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']); this.masterkey = Promise.resolve(promiseLike); } async sign(request, date = new Date()) { const key = await this.masterkey; const payload = this.getPayload(request, date); const hashed = await crypto.subtle.sign('HMAC', key, payload); const signature = rfc4648_1.base64.stringify(new Uint8Array(hashed)); request.headers.set('authorization', encodeURIComponent(`type=master&ver=1.0&sig=${signature}`)); request.headers.set('x-ms-date', date.toUTCString()); } getPayload(request, date) { const url = new URL(request.url); const { resourceType, resourceId } = this.pathnameToResource(url.pathname); const method = request.method.toLowerCase(); const text = `${method}\n${resourceType}\n${resourceId}\n${date .toUTCString() .toLowerCase()}\n\n`; return this.encoder.encode(text); } pathnameToResource(pathname) { const segments = pathname.split('/'); if (segments.length % 2 === 0) { const resourceType = segments[segments.length - 1]; const resourceId = segments.slice(1, segments.length - 1).join('/'); return { resourceType, resourceId }; } const resourceType = segments[segments.length - 2]; const resourceId = segments.slice(1, segments.length).join('/'); return { resourceType, resourceId }; } } exports.Signer = Signer; const signers = {}; function getSigner(masterKey) { if (!signers[masterKey]) { signers[masterKey] = new Signer(masterKey); } return signers[masterKey]; }