/* * This code was auto generated by AfterShip SDK Generator. * Do not edit the class manually. */ import crypto from "crypto"; import querystring from "querystring"; const SEPERATOR = "\n"; export enum AuthType { API_KEY = "API_KEY", AES = "AES", RSA = "RSA", } interface SignParams { url: string; method: string; body?: string; content_type?: string; date: string; headers: { [key: string]: any }; query?: any; private_key?: string; auth_type: string; } export class Authentication { public static sign(params: SignParams): string { const canonicalized_headers = this.canonicalizedHeaders(params.headers); const canonicalized_resource = this.canonicalizedResource( params.url, params.query, ); const sign_message = this.signMessage( params.method, params.date, canonicalized_headers, canonicalized_resource, params.body, params.content_type, ); if (params.auth_type === AuthType.AES) { return this.signAES(sign_message, params.private_key); } else if (params.auth_type === AuthType.RSA) { return this.signRSA(sign_message, params.private_key); } return ""; } private static signAES(message: any, private_key: string = ""): string { const hmac = crypto.createHmac("sha256", private_key); hmac.update(message); const signature = hmac.digest("base64"); return signature; } private static signRSA(message: any, private_key: string = ""): string { const signer = crypto.createSign("RSA-SHA256"); signer.update(message); const signature = signer.sign({ key: private_key, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST, }); return signature.toString("base64"); } public static signMessage( method: string, date: string, canonicalized_headers: string, canonicalized_resource: string, body?: string, content_type?: string, ): string { let result: string = method + SEPERATOR; let md5_body = ""; let _content_type = content_type; if (body === undefined || body === null || body.length === 0) { _content_type = ""; } else { const md5 = crypto.createHash("md5"); md5_body = md5.update(body).digest("hex").toUpperCase(); } result += md5_body + SEPERATOR; result += _content_type + SEPERATOR; result += date + SEPERATOR; result += canonicalized_headers + SEPERATOR; result += canonicalized_resource; return result; } private static canonicalizedHeaders(headers: { [key: string]: any }): string { const concatenate_headers: string[] = []; const all_header_keys = Object.keys(headers).sort(); for (const k of all_header_keys) { if (k.startsWith("as")) { const header_value = headers[k]; concatenate_headers.push( `${k.trim()}:${header_value ? header_value.toString().trim() : ""}`, ); } } return concatenate_headers.join("\n"); } private static canonicalizedResource(url: string, query: any): string { if (query) { const query_keys = Object.keys(query).sort(); const concatenate_querys: string[] = []; if (query_keys.length) { for (const k of query_keys) { let qeury_value = query[k]; qeury_value = qeury_value ? qeury_value.toString().trim() : ""; qeury_value = querystring.escape(qeury_value); concatenate_querys.push(`${k.trim()}=${qeury_value}`); } return `${url}?${concatenate_querys.join("&")}`; } } return url; } }