UNPKG

cnpmcore

Version:

Private NPM Registry for Enterprise

146 lines 12.3 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import crypto from 'node:crypto'; import { SingletonProto } from 'egg'; import binaries from "../../../../config/binaries.js"; import { BinaryType } from "../../enum/Binary.js"; import { BinaryAdapter } from "./AbstractBinary.js"; import { BucketBinary } from "./BucketBinary.js"; /** * NW.js binary adapter. * * Root directory: scraped from https://dl.nwjs.io/ (HTML index) * Sub directories: listed via Cloudflare R2 S3-compatible API (ListObjectsV2) * * The R2 bucket credentials are publicly available in the nwjs frontend page. * @see https://github.com/cnpm/cnpmcore/issues/891 */ let NwjsBinary = class NwjsBinary extends BucketBinary { constructor() { super(...arguments); // Cloudflare R2 S3-compatible endpoint for nwjs bucket this.r2Endpoint = 'https://6883a4a09c48918c64df1ec7ddb744ba.r2.cloudflarestorage.com'; this.r2BucketName = 'nwjs'; this.r2AccessKeyId = '90fdca5d031b05eed0ef896a56a9521a'; this.r2SecretAccessKey = '34eeb665b34bfb9b773a8ff763a15e76621f541fdbbadeca6ed23e6d99c878ad'; this.r2Region = 'auto'; } async fetch(dir) { const binaryConfig = binaries.nwjs; const isRootDir = dir === '/'; if (isRootDir) { return this.fetchRootDir(binaryConfig.distUrl); } return this.fetchSubDir(dir, binaryConfig); } async fetchRootDir(distUrl) { const xml = await this.requestXml(distUrl); if (!xml) return; const items = []; const re = /<td><a [^>]+?>([^<]+?\/)<\/a><\/td><td [^>]+?>([^>]+?)<\/td>/gi; const matchs = xml.matchAll(re); for (const m of matchs) { const name = m[1].trim(); // ignore live-build/ name if (name === 'live-build/') continue; const date = m[2].trim(); items.push({ name, isDir: true, url: '', size: '-', date, }); } return { items, nextParams: null }; } async fetchSubDir(dir, binaryConfig) { // /foo/ => foo/ const prefix = dir.slice(1); const xml = await this.requestR2Xml(prefix); if (!xml) return; return { items: this.parseItems(xml, dir, binaryConfig), nextParams: null }; } /** * Request R2 S3 ListObjectsV2 API with AWS Signature V4 authentication. */ async requestR2Xml(prefix) { const host = new URL(this.r2Endpoint).host; const now = new Date(); const amzDate = now .toISOString() .replace(/[-:]/g, '') .replace(/\.\d{3}/, ''); const dateStamp = amzDate.slice(0, 8); const method = 'GET'; const canonicalUri = `/${this.r2BucketName}`; // Build sorted query string const queryParams = new URLSearchParams({ delimiter: '/', 'list-type': '2', prefix: prefix, }); queryParams.sort(); const canonicalQueryString = queryParams.toString(); // Build canonical request const payloadHash = crypto.createHash('sha256').update('').digest('hex'); const canonicalHeaders = `host:${host}\nx-amz-content-sha256:${payloadHash}\nx-amz-date:${amzDate}\n`; const signedHeaders = 'host;x-amz-content-sha256;x-amz-date'; const canonicalRequest = [ method, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, payloadHash, ].join('\n'); // Build string to sign const credentialScope = `${dateStamp}/${this.r2Region}/s3/aws4_request`; const stringToSign = [ 'AWS4-HMAC-SHA256', amzDate, credentialScope, crypto.createHash('sha256').update(canonicalRequest).digest('hex'), ].join('\n'); // Calculate signature const signingKey = this.getSignatureKey(this.r2SecretAccessKey, dateStamp, this.r2Region, 's3'); const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex'); const authorization = `AWS4-HMAC-SHA256 Credential=${this.r2AccessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`; const url = `${this.r2Endpoint}/${this.r2BucketName}?${canonicalQueryString}`; const { status, data, headers } = await this.httpclient.request(url, { timeout: 30_000, followRedirect: true, gzip: true, headers: { Authorization: authorization, 'X-Amz-Content-Sha256': payloadHash, 'X-Amz-Date': amzDate, }, }); const xml = data.toString(); if (status !== 200) { this.logger.warn('[NwjsBinary.requestR2Xml:non-200-status] url: %s, status: %s, headers: %j, xml: %j', url, status, headers, xml); return ''; } return xml; } getSignatureKey(key, dateStamp, region, service) { const kDate = crypto.createHmac('sha256', `AWS4${key}`).update(dateStamp).digest(); const kRegion = crypto.createHmac('sha256', kDate).update(region).digest(); const kService = crypto.createHmac('sha256', kRegion).update(service).digest(); return crypto.createHmac('sha256', kService).update('aws4_request').digest(); } }; NwjsBinary = __decorate([ SingletonProto(), BinaryAdapter(BinaryType.Nwjs) ], NwjsBinary); export { NwjsBinary }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTndqc0JpbmFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2FwcC9jb21tb24vYWRhcHRlci9iaW5hcnkvTndqc0JpbmFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFFakMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUVyQyxPQUFPLFFBQVEsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN0RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBcUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFakQ7Ozs7Ozs7O0dBUUc7QUFHSSxJQUFNLFVBQVUsR0FBaEIsTUFBTSxVQUFXLFNBQVEsWUFBWTtJQUFyQzs7UUFDTCx1REFBdUQ7UUFDL0MsZUFBVSxHQUFHLG1FQUFtRSxDQUFDO1FBQ2pGLGlCQUFZLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLGtCQUFhLEdBQUcsa0NBQWtDLENBQUM7UUFDbkQsc0JBQWlCLEdBQUcsa0VBQWtFLENBQUM7UUFDdkYsYUFBUSxHQUFHLE1BQU0sQ0FBQztJQWtJNUIsQ0FBQztJQWhJQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQVc7UUFDckIsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNuQyxNQUFNLFNBQVMsR0FBRyxHQUFHLEtBQUssR0FBRyxDQUFDO1FBRTlCLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFTyxLQUFLLENBQUMs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