0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00
logto/packages/connector-aliyun-dm/src/utils.ts
Gao Sun c9286dcda2
chore: create codeql-analysis.yml (#1560)
* chore: create codeql-analysis.yml

* refactor: ignore test files

* refactor(connector): fix alerts
2022-07-15 22:12:44 +08:00

66 lines
1.7 KiB
TypeScript

import { createHmac } from 'crypto';
import got from 'got';
import { PublicParameters } from './types';
// Aliyun has special escape rules.
// https://help.aliyun.com/document_detail/29442.html
const escaper = (string_: string) =>
encodeURIComponent(string_)
.replace(/\*/g, '%2A')
.replace(/'/g, '%27')
.replace(/!/g, '%21')
.replace(/"/g, '%22')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\+/g, '%2B');
export const getSignature = (
parameters: Record<string, string>,
secret: string,
method: string
) => {
const canonicalizedQuery = Object.keys(parameters)
.map((key) => {
const value = parameters[key];
return value === undefined ? '' : `${escaper(key)}=${escaper(value)}`;
})
.filter(Boolean)
.slice()
.sort()
.join('&');
const stringToSign = `${method.toUpperCase()}&${escaper('/')}&${escaper(canonicalizedQuery)}`;
return createHmac('sha1', `${secret}&`).update(stringToSign).digest('base64');
};
export const request = async (
url: string,
parameters: PublicParameters & Record<string, string>,
accessKeySecret: string
) => {
const finalParameters: Record<string, string> = {
...parameters,
SignatureNonce: String(Math.random()),
Timestamp: new Date().toISOString(),
};
const signature = getSignature(finalParameters, accessKeySecret, 'POST');
const payload = new URLSearchParams();
for (const [key, value] of Object.entries(finalParameters)) {
payload.append(key, value);
}
payload.append('Signature', signature);
return got.post({
url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
form: payload,
});
};