0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00
logto/packages/connector-aliyun-dm/src/utils.ts
Darcy Ye 3925424316
refactor(connectors): use zod guard instead of got generic and elaborate error info (#1078)
* feat(alipay): use zod parse instead of got response generic

* feat(alipay): fix expires_in and re_expires_in type

* feat(alipay): extract errorHandler function to map HTTP error to connector error

* feat(alipay-native): refactor as alipay

* feat(aliyun-dm): use zod parser for type guard and extract error handler

* feat(aliyun-sms): extract error handler

* feat(facebook): use zod parser

* feat(github): use zod parser

* feat(google): use zod parser

* feat(wechat-web): use zod parser and wrap error handler

* feat(wechat-native): use zod parser and wrap error handler
2022-06-10 10:41:45 +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(/\+/, '%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,
});
};