0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00
logto/packages/connectors/connector-aliyun-dm/src/utils.ts
Gao Sun 947de83173
chore: upgrade configs (#4132)
* chore: upgrade configs

* chore: fix lint errors
2023-07-07 17:17:21 +00:00

65 lines
1.9 KiB
TypeScript

import { type Optional } from '@silverhand/essentials';
import { got } from 'got';
import { createHmac, randomUUID } from 'node:crypto';
import type { PublicParameters } from './types.js';
// Aliyun has special escape rules.
// https://help.aliyun.com/document_detail/29442.html
const escaper = (string_: string) =>
encodeURIComponent(string_)
.replaceAll('!', '%21')
.replaceAll('"', '%22')
.replaceAll("'", '%27')
.replaceAll('(', '%28')
.replaceAll(')', '%29')
.replaceAll('*', '%2A')
.replaceAll('+', '%2B');
// Format date string to 'YYYY-MM-DDThh:mm:ssZ' format.
const formatDateString = (date: Date) => {
const rawString = date.toISOString();
return rawString.replace(/\.\d{3}Z$/, 'Z'); // Trim milliseconds.
};
export const getSignature = (
parameters: Record<string, string>,
secret: string,
method: string
) => {
const canonicalizedQuery = Object.entries(parameters)
.map(([key, value]) => {
return `${escaper(key)}=${escaper(value)}`;
})
.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 = Object.entries<Optional<string>>({
...parameters,
SignatureNonce: randomUUID(),
Timestamp: formatDateString(new Date()),
}).reduce<Record<string, string>>(
(result, [key, value]) => (value === undefined ? result : { ...result, [key]: value }),
{}
);
const signature = getSignature(finalParameters, accessKeySecret, 'POST');
return got.post({
url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
form: { ...finalParameters, Signature: signature },
});
};