@wix/sdk 1.7.2 → 1.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,9 @@
1
1
  import { AuthenticationStrategy } from '@wix/sdk-types';
2
2
  export type WixAppOAuthStrategy = AuthenticationStrategy & {
3
- getInstallUrl({ redirectUrl }: {
3
+ getInstallUrl(opts: {
4
4
  redirectUrl: string;
5
+ state?: string;
6
+ token?: string;
5
7
  }): string;
6
8
  handleOAuthCallback(url: string, opts?: {
7
9
  state: string;
@@ -18,7 +20,7 @@ export type WixAppOAuthStrategy = AuthenticationStrategy & {
18
20
  * @param opts.appId The Wix App ID
19
21
  * @param opts.appSecret The Wix App Secret
20
22
  * @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API
21
- * @param opts.publicKey An optional public key for validating webhook requests
23
+ * @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys)
22
24
  * @returns An authentication strategy that can be used with WixClient
23
25
  * @example
24
26
  * ```ts
@@ -1,4 +1,5 @@
1
1
  import { verify } from 'jsonwebtoken';
2
+ import { parsePublicKeyIfEncoded } from '../helpers.js';
2
3
  /**
3
4
  * Creates an authentication strategy for Wix Apps OAuth installation process.
4
5
  * Use this authentication strategy when making requests to Wix APIs from your Wix App backend.
@@ -6,7 +7,7 @@ import { verify } from 'jsonwebtoken';
6
7
  * @param opts.appId The Wix App ID
7
8
  * @param opts.appSecret The Wix App Secret
8
9
  * @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API
9
- * @param opts.publicKey An optional public key for validating webhook requests
10
+ * @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys)
10
11
  * @returns An authentication strategy that can be used with WixClient
11
12
  * @example
12
13
  * ```ts
@@ -40,8 +41,17 @@ import { verify } from 'jsonwebtoken';
40
41
  export function WixAppOAuthStrategy(opts) {
41
42
  let refreshToken = opts.refreshToken;
42
43
  return {
43
- getInstallUrl({ redirectUrl }) {
44
- return `https://www.wix.com/installer/install?appId=${opts.appId}&redirectUrl=${redirectUrl}`;
44
+ getInstallUrl({ redirectUrl, token, state }) {
45
+ const params = new URLSearchParams();
46
+ params.set('redirectUrl', redirectUrl);
47
+ params.set('appId', opts.appId);
48
+ if (state) {
49
+ params.set('state', state);
50
+ }
51
+ if (token) {
52
+ params.set('token', token);
53
+ }
54
+ return `https://www.wix.com/installer/install?${params.toString()}`;
45
55
  },
46
56
  async handleOAuthCallback(url, oauthOpts) {
47
57
  if (!opts.appSecret) {
@@ -110,11 +120,17 @@ export function WixAppOAuthStrategy(opts) {
110
120
  },
111
121
  };
112
122
  },
113
- decodeJWT(token) {
123
+ decodeJWT(token, verifyCallerClaims = false) {
114
124
  if (!opts.publicKey) {
115
125
  throw new Error('Missing public key. Make sure to pass it to the WixAppOAuthStrategy');
116
126
  }
117
- const decoded = verify(token, opts.publicKey);
127
+ const publicKey = parsePublicKeyIfEncoded(opts.publicKey);
128
+ const decoded = verify(token, publicKey, verifyCallerClaims
129
+ ? {
130
+ issuer: 'wix.com',
131
+ audience: opts.appId,
132
+ }
133
+ : undefined);
118
134
  return {
119
135
  decoded,
120
136
  valid: true,
@@ -2,3 +2,4 @@ export declare const getDefaultContentHeader: (options: RequestInit | undefined)
2
2
  'Content-Type'?: string;
3
3
  };
4
4
  export declare const isObject: (val: any) => val is Object;
5
+ export declare function parsePublicKeyIfEncoded(publicKey: string): string;
package/build/helpers.js CHANGED
@@ -9,3 +9,15 @@ export const getDefaultContentHeader = (options) => {
9
9
  return {};
10
10
  };
11
11
  export const isObject = (val) => val && typeof val === 'object' && !Array.isArray(val);
12
+ export function parsePublicKeyIfEncoded(publicKey) {
13
+ if (publicKey.includes('\n') || publicKey.includes('\r')) {
14
+ // publicKey is multi-line string, can be used as is
15
+ return publicKey.trim();
16
+ }
17
+ else {
18
+ // publicKey is base64 encoded
19
+ return typeof btoa !== 'undefined'
20
+ ? btoa(publicKey)
21
+ : Buffer.from(publicKey, 'base64').toString('utf-8');
22
+ }
23
+ }
@@ -1,4 +1,4 @@
1
- import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition } from '@wix/sdk-types';
1
+ import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition, SPIDefinition } from '@wix/sdk-types';
2
2
  import { ConditionalExcept, EmptyObject } from 'type-fest';
3
3
  import { AmbassadorFunctionDescriptor, BuildAmbassadorFunction } from './ambassador-modules.js';
4
4
  import { PublicMetadata } from './common.js';
@@ -67,6 +67,20 @@ export type WixClient<H extends Host<any> | undefined = undefined, Z extends Aut
67
67
  processRequest<ExpectedEvents extends EventDefinition<any>[] = []>(request: Request, opts?: {
68
68
  expectedEvents: ExpectedEvents;
69
69
  }): Promise<ProcessedEvent<ExpectedEvents>>;
70
+ apps: {
71
+ AppInstalled: EventDefinition<{
72
+ appId: string;
73
+ originInstanceId: string;
74
+ }>;
75
+ AppRemoved: EventDefinition<{
76
+ appId: string;
77
+ }>;
78
+ };
79
+ };
80
+ spi: <S extends SPIDefinition<any, any>>() => {
81
+ process(jwt: string): S['__input'];
82
+ processRequest(request: Request): Promise<S['__input']>;
83
+ result(result: S['__result']): S['__result'];
70
84
  };
71
85
  } & BuildDescriptors<T, H>;
72
86
  type ResolvePossibleEvents<T extends EventDefinition<any>[]> = {
@@ -116,6 +116,37 @@ export function createClient(config) {
116
116
  const body = await request.text();
117
117
  return this.process(body, opts);
118
118
  },
119
+ apps: {
120
+ AppInstalled: {
121
+ type: 'AppInstalled',
122
+ __payload: void 0,
123
+ },
124
+ AppRemoved: {
125
+ type: 'AppRemoved',
126
+ __payload: void 0,
127
+ },
128
+ },
129
+ },
130
+ spi() {
131
+ return {
132
+ process(jwt) {
133
+ if (!authStrategy.decodeJWT) {
134
+ throw new Error('decodeJWT is not supported by the authentication strategy');
135
+ }
136
+ const { decoded, valid } = authStrategy.decodeJWT(jwt, true);
137
+ if (!valid) {
138
+ throw new Error('JWT is not valid');
139
+ }
140
+ return decoded.data;
141
+ },
142
+ async processRequest(request) {
143
+ const body = await request.text();
144
+ return this.process(body);
145
+ },
146
+ result(result) {
147
+ return result;
148
+ },
149
+ };
119
150
  },
120
151
  };
121
152
  }
@@ -1,7 +1,9 @@
1
1
  import { AuthenticationStrategy } from '@wix/sdk-types';
2
2
  export type WixAppOAuthStrategy = AuthenticationStrategy & {
3
- getInstallUrl({ redirectUrl }: {
3
+ getInstallUrl(opts: {
4
4
  redirectUrl: string;
5
+ state?: string;
6
+ token?: string;
5
7
  }): string;
6
8
  handleOAuthCallback(url: string, opts?: {
7
9
  state: string;
@@ -18,7 +20,7 @@ export type WixAppOAuthStrategy = AuthenticationStrategy & {
18
20
  * @param opts.appId The Wix App ID
19
21
  * @param opts.appSecret The Wix App Secret
20
22
  * @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API
21
- * @param opts.publicKey An optional public key for validating webhook requests
23
+ * @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys)
22
24
  * @returns An authentication strategy that can be used with WixClient
23
25
  * @example
24
26
  * ```ts
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WixAppOAuthStrategy = void 0;
4
4
  const jsonwebtoken_1 = require("jsonwebtoken");
5
+ const helpers_js_1 = require("../helpers.js");
5
6
  /**
6
7
  * Creates an authentication strategy for Wix Apps OAuth installation process.
7
8
  * Use this authentication strategy when making requests to Wix APIs from your Wix App backend.
@@ -9,7 +10,7 @@ const jsonwebtoken_1 = require("jsonwebtoken");
9
10
  * @param opts.appId The Wix App ID
10
11
  * @param opts.appSecret The Wix App Secret
11
12
  * @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API
12
- * @param opts.publicKey An optional public key for validating webhook requests
13
+ * @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys)
13
14
  * @returns An authentication strategy that can be used with WixClient
14
15
  * @example
15
16
  * ```ts
@@ -43,8 +44,17 @@ const jsonwebtoken_1 = require("jsonwebtoken");
43
44
  function WixAppOAuthStrategy(opts) {
44
45
  let refreshToken = opts.refreshToken;
45
46
  return {
46
- getInstallUrl({ redirectUrl }) {
47
- return `https://www.wix.com/installer/install?appId=${opts.appId}&redirectUrl=${redirectUrl}`;
47
+ getInstallUrl({ redirectUrl, token, state }) {
48
+ const params = new URLSearchParams();
49
+ params.set('redirectUrl', redirectUrl);
50
+ params.set('appId', opts.appId);
51
+ if (state) {
52
+ params.set('state', state);
53
+ }
54
+ if (token) {
55
+ params.set('token', token);
56
+ }
57
+ return `https://www.wix.com/installer/install?${params.toString()}`;
48
58
  },
49
59
  async handleOAuthCallback(url, oauthOpts) {
50
60
  if (!opts.appSecret) {
@@ -113,11 +123,17 @@ function WixAppOAuthStrategy(opts) {
113
123
  },
114
124
  };
115
125
  },
116
- decodeJWT(token) {
126
+ decodeJWT(token, verifyCallerClaims = false) {
117
127
  if (!opts.publicKey) {
118
128
  throw new Error('Missing public key. Make sure to pass it to the WixAppOAuthStrategy');
119
129
  }
120
- const decoded = (0, jsonwebtoken_1.verify)(token, opts.publicKey);
130
+ const publicKey = (0, helpers_js_1.parsePublicKeyIfEncoded)(opts.publicKey);
131
+ const decoded = (0, jsonwebtoken_1.verify)(token, publicKey, verifyCallerClaims
132
+ ? {
133
+ issuer: 'wix.com',
134
+ audience: opts.appId,
135
+ }
136
+ : undefined);
121
137
  return {
122
138
  decoded,
123
139
  valid: true,
@@ -2,3 +2,4 @@ export declare const getDefaultContentHeader: (options: RequestInit | undefined)
2
2
  'Content-Type'?: string;
3
3
  };
4
4
  export declare const isObject: (val: any) => val is Object;
5
+ export declare function parsePublicKeyIfEncoded(publicKey: string): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isObject = exports.getDefaultContentHeader = void 0;
3
+ exports.parsePublicKeyIfEncoded = exports.isObject = exports.getDefaultContentHeader = void 0;
4
4
  // we follow a simplified version of the axios convention
5
5
  // https://github.com/axios/axios/blob/649d739288c8e2c55829ac60e2345a0f3439c730/lib/defaults/index.js#L65
6
6
  const getDefaultContentHeader = (options) => {
@@ -14,3 +14,16 @@ const getDefaultContentHeader = (options) => {
14
14
  exports.getDefaultContentHeader = getDefaultContentHeader;
15
15
  const isObject = (val) => val && typeof val === 'object' && !Array.isArray(val);
16
16
  exports.isObject = isObject;
17
+ function parsePublicKeyIfEncoded(publicKey) {
18
+ if (publicKey.includes('\n') || publicKey.includes('\r')) {
19
+ // publicKey is multi-line string, can be used as is
20
+ return publicKey.trim();
21
+ }
22
+ else {
23
+ // publicKey is base64 encoded
24
+ return typeof btoa !== 'undefined'
25
+ ? btoa(publicKey)
26
+ : Buffer.from(publicKey, 'base64').toString('utf-8');
27
+ }
28
+ }
29
+ exports.parsePublicKeyIfEncoded = parsePublicKeyIfEncoded;
@@ -1,4 +1,4 @@
1
- import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition } from '@wix/sdk-types';
1
+ import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition, SPIDefinition } from '@wix/sdk-types';
2
2
  import { ConditionalExcept, EmptyObject } from 'type-fest';
3
3
  import { AmbassadorFunctionDescriptor, BuildAmbassadorFunction } from './ambassador-modules.js';
4
4
  import { PublicMetadata } from './common.js';
@@ -67,6 +67,20 @@ export type WixClient<H extends Host<any> | undefined = undefined, Z extends Aut
67
67
  processRequest<ExpectedEvents extends EventDefinition<any>[] = []>(request: Request, opts?: {
68
68
  expectedEvents: ExpectedEvents;
69
69
  }): Promise<ProcessedEvent<ExpectedEvents>>;
70
+ apps: {
71
+ AppInstalled: EventDefinition<{
72
+ appId: string;
73
+ originInstanceId: string;
74
+ }>;
75
+ AppRemoved: EventDefinition<{
76
+ appId: string;
77
+ }>;
78
+ };
79
+ };
80
+ spi: <S extends SPIDefinition<any, any>>() => {
81
+ process(jwt: string): S['__input'];
82
+ processRequest(request: Request): Promise<S['__input']>;
83
+ result(result: S['__result']): S['__result'];
70
84
  };
71
85
  } & BuildDescriptors<T, H>;
72
86
  type ResolvePossibleEvents<T extends EventDefinition<any>[]> = {
@@ -119,6 +119,37 @@ function createClient(config) {
119
119
  const body = await request.text();
120
120
  return this.process(body, opts);
121
121
  },
122
+ apps: {
123
+ AppInstalled: {
124
+ type: 'AppInstalled',
125
+ __payload: void 0,
126
+ },
127
+ AppRemoved: {
128
+ type: 'AppRemoved',
129
+ __payload: void 0,
130
+ },
131
+ },
132
+ },
133
+ spi() {
134
+ return {
135
+ process(jwt) {
136
+ if (!authStrategy.decodeJWT) {
137
+ throw new Error('decodeJWT is not supported by the authentication strategy');
138
+ }
139
+ const { decoded, valid } = authStrategy.decodeJWT(jwt, true);
140
+ if (!valid) {
141
+ throw new Error('JWT is not valid');
142
+ }
143
+ return decoded.data;
144
+ },
145
+ async processRequest(request) {
146
+ const body = await request.text();
147
+ return this.process(body);
148
+ },
149
+ result(result) {
150
+ return result;
151
+ },
152
+ };
122
153
  },
123
154
  };
124
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/sdk",
3
- "version": "1.7.2",
3
+ "version": "1.7.4",
4
4
  "license": "UNLICENSED",
5
5
  "author": {
6
6
  "name": "Ronny Ringel",
@@ -62,7 +62,7 @@
62
62
  "@wix/identity": "^1.0.72",
63
63
  "@wix/image-kit": "^1.50.0",
64
64
  "@wix/redirects": "^1.0.32",
65
- "@wix/sdk-types": "^1.5.5",
65
+ "@wix/sdk-types": "^1.5.6",
66
66
  "crypto-js": "^4.2.0",
67
67
  "jsonwebtoken": "^9.0.2",
68
68
  "pkce-challenge": "^3.1.0",
@@ -78,10 +78,11 @@
78
78
  "@types/jsonwebtoken": "^9.0.5",
79
79
  "@types/node": "^20.10.6",
80
80
  "@vitest/ui": "^1.1.3",
81
- "@wix/ecom": "^1.0.473",
82
- "@wix/events": "^1.0.144",
81
+ "@wix/ecom": "^1.0.474",
82
+ "@wix/events": "^1.0.145",
83
83
  "@wix/metro": "^1.0.73",
84
- "@wix/metro-runtime": "^1.1616.0",
84
+ "@wix/metro-runtime": "^1.1618.0",
85
+ "@wix/sdk-runtime": "0.2.7",
85
86
  "eslint": "^8.56.0",
86
87
  "eslint-config-sdk": "0.0.0",
87
88
  "graphql": "^16.8.0",
@@ -115,5 +116,5 @@
115
116
  "wallaby": {
116
117
  "autoDetect": true
117
118
  },
118
- "falconPackageHash": "c93d4242558d1559e8e7149680612d8aca349adb52ef06a00050f11d"
119
+ "falconPackageHash": "93a9673030401f9f114208015d7df832e9f3e9b1189763fcd4380c61"
119
120
  }