From 7bbe8273cc55bc93e18a908cb45e48510240aa37 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Fri, 8 Jul 2022 11:31:49 +0800 Subject: [PATCH] chore(connector): add optional charset field to Alipay web config (#1460) --- packages/connector-alipay/README.md | 26 +++++++++++-------- .../docs/config-template.json | 3 ++- packages/connector-alipay/src/constant.ts | 2 ++ packages/connector-alipay/src/index.test.ts | 6 ++++- packages/connector-alipay/src/index.ts | 11 +++++--- packages/connector-alipay/src/mock.ts | 3 ++- packages/connector-alipay/src/types.ts | 3 ++- packages/connector-alipay/src/utils.ts | 4 +-- 8 files changed, 37 insertions(+), 21 deletions(-) diff --git a/packages/connector-alipay/README.md b/packages/connector-alipay/README.md index 8b6811c16..681a720e7 100644 --- a/packages/connector-alipay/README.md +++ b/packages/connector-alipay/README.md @@ -44,15 +44,17 @@ Alipay Web connector is designed for desktop Web applications. It takes advantag 3. Fill out the Logto connector settings: - Fill out the `appId` field with APPID you've got from step 1. - Fill out the `privateKey` field with contents from the private key file mentioned in step 2. Remember to use '\n' to replace all newlines. - - Fill out the `signType` filed with 'RSA2' due to the `Public key` signing mode we chose in step 7 of **Create And Configure Alipay Apps**. + - Fill out the `signType` field with 'RSA2' due to the `Public key` signing mode we chose in step 7 of **Create And Configure Alipay Apps**. + - Fill out the `charset` field with either 'GBK' or 'UTF8'. You can leave this field blank as it is OPTIONAL. The default value is set to be 'UTF8'. ### Config types -| Name | Type | Enum values | -|:----------:|:-----------:|:---------------:| -| appId | string | N/A | -| privateKey | string | N/A | -| signType | enum string | 'RSA' \| 'RSA2' | +| Name | Type | Enum values | +|------------|------------------------|------------------------------| +| appId | string | N/A | +| privateKey | string | N/A | +| signType | enum string | 'RSA' \| 'RSA2' | +| charset | enum string (OPTIONAL) | 'GBK' \| 'UTF8' \| undefined | ## Test Alipay web connector @@ -91,14 +93,16 @@ Once Alipay web connector is enabled, you can build and run your web app to see - 将你在第 1 步中获取的 APPID 填入 `appId` 字段。 - 将你在第 2 步中获得的密钥对的私钥填入 `privateKey` 字段,使用 '\n' 换行。 - 将你在第 2 步中所获得的密钥的签名模式 'RSA2' 填入 `signType` 字段。 + - 在 `charset` 字段中填入 'GBK' 或 'UTF8' 字符串。这个字段也可以选择不填,此时我们会使用 'UTF8' 的默认值。 ### 配置类型 -| 名称 | 类型 | 枚举值 | -|:----------:|:-----------:|:---------------:| -| appId | string | N/A | -| privateKey | string | N/A | -| signType | enum string | 'RSA' \| 'RSA2' | +| 名称 | 类型 | 枚举值 | +|------------|------------------------|------------------------------| +| appId | string | N/A | +| privateKey | string | N/A | +| signType | enum string | 'RSA' \| 'RSA2' | +| charset | enum string (OPTIONAL) | 'GBK' \| 'UTF8' \| undefined | ## 测试支付宝网页连接器 diff --git a/packages/connector-alipay/docs/config-template.json b/packages/connector-alipay/docs/config-template.json index 0607ce1f7..d3eca68b8 100644 --- a/packages/connector-alipay/docs/config-template.json +++ b/packages/connector-alipay/docs/config-template.json @@ -1,5 +1,6 @@ { "appId": "", "signType": "", - "privateKey": "" + "privateKey": "", + "charset": "" } diff --git a/packages/connector-alipay/src/constant.ts b/packages/connector-alipay/src/constant.ts index 992efce17..00f266689 100644 --- a/packages/connector-alipay/src/constant.ts +++ b/packages/connector-alipay/src/constant.ts @@ -11,6 +11,8 @@ export const alipaySigningAlgorithmMapping = { RSA2: 'RSA-SHA256', } as const; export const alipaySigningAlgorithms = ['RSA', 'RSA2'] as const; +export const charsetEnum = ['GBK', 'UTF8'] as const; +export const fallbackCharset = 'UTF8'; export const defaultMetadata: ConnectorMetadata = { id: 'alipay-web', diff --git a/packages/connector-alipay/src/index.test.ts b/packages/connector-alipay/src/index.test.ts index 393161e58..02230ad8a 100644 --- a/packages/connector-alipay/src/index.test.ts +++ b/packages/connector-alipay/src/index.test.ts @@ -17,7 +17,11 @@ describe('validateConfig', () => { it('should pass on valid config', async () => { await expect( - alipayMethods.validateConfig({ appId: 'appId', privateKey: 'privateKey', signType: 'RSA' }) + alipayMethods.validateConfig({ + appId: 'appId', + privateKey: 'privateKey', + signType: 'RSA', + }) ).resolves.not.toThrow(); }); diff --git a/packages/connector-alipay/src/index.ts b/packages/connector-alipay/src/index.ts index c2cfe4380..cb3254854 100644 --- a/packages/connector-alipay/src/index.ts +++ b/packages/connector-alipay/src/index.ts @@ -29,6 +29,7 @@ import { defaultMetadata, defaultTimeout, timestampFormat, + fallbackCharset, } from './constant'; import { alipayConfigGuard, @@ -72,6 +73,7 @@ export default class AlipayConnector implements SocialConnector { }; public getAccessToken = async (code: string, config: AlipayConfig) => { + const { charset, ...rest } = config; const initSearchParameters = { method: methodForAccessToken, format: 'JSON', @@ -79,8 +81,8 @@ export default class AlipayConnector implements SocialConnector { version: '1.0', grant_type: 'authorization_code', code, - charset: 'UTF8', - ...config, + ...rest, + charset: charset ?? fallbackCharset, }; const signedSearchParameters = this.signingParameters(initSearchParameters); @@ -119,6 +121,7 @@ export default class AlipayConnector implements SocialConnector { new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters) ); + const { charset, ...rest } = config; const initSearchParameters = { method: methodForUserInfo, format: 'JSON', @@ -127,8 +130,8 @@ export default class AlipayConnector implements SocialConnector { grant_type: 'authorization_code', auth_token: accessToken, biz_content: JSON.stringify({}), - charset: 'UTF8', - ...config, + ...rest, + charset: charset ?? fallbackCharset, }; const signedSearchParameters = this.signingParameters(initSearchParameters); diff --git a/packages/connector-alipay/src/mock.ts b/packages/connector-alipay/src/mock.ts index c6fa2b39d..27624fff4 100644 --- a/packages/connector-alipay/src/mock.ts +++ b/packages/connector-alipay/src/mock.ts @@ -6,6 +6,7 @@ export const mockedAlipayConfig: AlipayConfig = { appId: '2021000000000000', signType: 'RSA2', privateKey: '', + charset: 'UTF8', }; export const mockedAlipayConfigWithValidPrivateKey: AlipayConfig = { @@ -13,6 +14,7 @@ export const mockedAlipayConfigWithValidPrivateKey: AlipayConfig = { signType: 'RSA2', privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC52SvnlRfzJJDR\nA1h4MX2JWV7Yt1j+1gvtQuLh0RYbE0AgRyz8CXFcJegO8gNyUQ05vrc1RMVzvNh8\njfjLpIX8an88KE4FyoG5P8NWrwPw5ZXOnzdvNxAV8QWOU+rT4WAdCsx4++mLlb5v\nGL18R77f3WLgY23bFtcGr9q7/qOaLzNxEe4idX1eLf7Ba/gQRY0awA55/Epd1Mi7\nLqTfxTd11PoBZQPe0vnuChp3P2l1MNpIJ5G1eQ4RXgI4UMClEbGRlBN7GUlXy5p7\ng6RtvOcwmBNoE4i0/HbvaanY3u7oenST3iSzEXa2hXMjnZPvg0G4Y5mq/V6XJPTh\nJrFc9XzFAgMBAAECggEAXfmNtN10LdN4kugBLU3BL9mMF0Om8b1kbIXc2djzN5+l\nVm0HNy7DLphQXnZL/ds0N9XTKFFtEpgUU+8qNjcsNTXYvp+WzGDY9cZjTQrUkFRX\nSxLBYjBSpvWoHI8ceCVHh4f1Wtvu/VEr6Vt2PUi+IM7+d35vh1BmTJBRp6wcKBMH\nXdfjWIi5z37pTXD3OTfUjBCtzA2DX0vY6UTsmD9UI0Mb6IJdT6qugiGODFdlsduA\nWJoZlXV1VbHcvGt7DoeQgzA45sr5siUnm+ntTVBHOR/hoZQrr0DY/O/MLKYUj/+r\nZMKKpx/7VHnWfMia2EOHfjW8vUlnraUzI+5E2/FzIQKBgQDgi7S7pfRux8YONGP2\nRtHPkF8d0YllsfKedhqF3cQlJ1dhxzVqHOi1IFn6ttuuYy5UsP5apYa2kj2UUPCa\nZGGi19Vnc+RHThpR4K6/OGFrpbINAgiVJLj7F8GXzqeA7W2ZHMp1R+oB+oTxih6t\nU0dbeTP01kbBV1/7+ZUKPhLE6QKBgQDT4cMgq01F/WIGGd1GUHZQjH5bqtNiJpIf\n2Q2OTw/gn1DVnwDXpHuXPxtC3NRoaRW/dTqsF6AAkMja3voPM3sYJurGBdU8pZPC\nquc9mqqu6TR5gX3KL1lSESvMBEgfLUy/f0gI3JNw1mG17pIhnXmOB2be3HfZPcj3\nwKWlluY/fQKBgDLll97c3A3sPGll2K6vGMmqmNTCdRlW/36JmLN1NAuT4kuoguP9\nj4XWwm6A2kSp+It73vue/20MsuaWfiMQ08y8jYO4kirTekXK3vE7D2H+GeC28EkW\nHNPVa61ES1V++9Oz4fQ5i8JNDatOOmvhL5B9ZZh+pWUXsAsGZJEAxvJZAoGAMPHO\n5GYN1KQil6wz3EFMA3Fg4wYEDIFCcg7uvbfvwACtaJtxU18QmbCfOIPQoUndFzwa\nUJSohljrvPuTIh3PSpX618GTL45EIszd2/I1iXAfig3qo+DqLjX/OwKmMmWBfB8H\n4dwqRv+O1LsGkLNS2AdHsSWWnd1S5kBfQ3AnQfUCgYACM8ldXZv7uGt9uZBmxile\nB0Hg5w7F1v9VD/m9ko+INAISz8OVkD83pCEoyHwlr20JjiF+yzAakOuq6rBi+l/V\n1veSiTDUcZhciuq1G178dFYepJqisFBu7bAM+WBS4agTTtxdSLZkHeS4VX+H3DOc\ntri43NXw6QS7uQ5/+2TsEw==\n-----END PRIVATE KEY-----', + charset: 'UTF8', }; export const mockedAlipayPublicParameters = { @@ -20,6 +22,5 @@ export const mockedAlipayPublicParameters = { grantType: 'authorization_code', timestamp: mockedTimestamp, version: '1.0', - charset: 'UTF8', method: '', }; diff --git a/packages/connector-alipay/src/types.ts b/packages/connector-alipay/src/types.ts index b901e3c9e..1fdd3a1d6 100644 --- a/packages/connector-alipay/src/types.ts +++ b/packages/connector-alipay/src/types.ts @@ -1,11 +1,12 @@ import { z } from 'zod'; -import { alipaySigningAlgorithms } from './constant'; +import { alipaySigningAlgorithms, charsetEnum } from './constant'; export const alipayConfigGuard = z.object({ appId: z.string(), privateKey: z.string(), signType: z.enum(alipaySigningAlgorithms), + charset: z.enum(charsetEnum).optional(), }); export type AlipayConfig = z.infer; diff --git a/packages/connector-alipay/src/utils.ts b/packages/connector-alipay/src/utils.ts index da7c8121d..cc11c2ad2 100644 --- a/packages/connector-alipay/src/utils.ts +++ b/packages/connector-alipay/src/utils.ts @@ -3,7 +3,7 @@ import * as crypto from 'crypto'; import * as iconv from 'iconv-lite'; import snakeCaseKeys from 'snakecase-keys'; -import { alipaySigningAlgorithmMapping } from './constant'; +import { alipaySigningAlgorithmMapping, fallbackCharset } from './constant'; import { AlipayConfig } from './types'; export type SigningParameters = ( @@ -33,7 +33,7 @@ export const signingParameters: SigningParameters = ( if (value) { // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - return `${key}=${iconv.encode(value, rest.charset ?? 'UTF8')}`; + return `${key}=${iconv.encode(value, rest.charset ?? fallbackCharset)}`; } return '';