@wix/sdk
Advanced tools
Comparing version
import { AuthenticationStrategy } from '@wix/sdk-types'; | ||
export type WixAppOAuthStrategy = AuthenticationStrategy & { | ||
getInstallUrl({ redirectUrl }: { | ||
getInstallUrl(opts: { | ||
redirectUrl: string; | ||
state?: string; | ||
token?: string; | ||
}): string; | ||
@@ -21,3 +23,3 @@ handleOAuthCallback(url: string, opts?: { | ||
* @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API | ||
* @param opts.publicKey An optional public key for validating webhook requests | ||
* @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys) | ||
* @returns An authentication strategy that can be used with WixClient | ||
@@ -24,0 +26,0 @@ * @example |
import { verify } from 'jsonwebtoken'; | ||
import { parsePublicKeyIfEncoded } from '../helpers.js'; | ||
/** | ||
@@ -9,3 +10,3 @@ * Creates an authentication strategy for Wix Apps OAuth installation process. | ||
* @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API | ||
* @param opts.publicKey An optional public key for validating webhook requests | ||
* @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys) | ||
* @returns An authentication strategy that can be used with WixClient | ||
@@ -44,4 +45,13 @@ * @example | ||
return { | ||
getInstallUrl({ redirectUrl }) { | ||
return `https://www.wix.com/installer/install?appId=${opts.appId}&redirectUrl=${redirectUrl}`; | ||
getInstallUrl({ redirectUrl, token, state }) { | ||
const params = new URLSearchParams(); | ||
params.set('redirectUrl', redirectUrl); | ||
params.set('appId', opts.appId); | ||
if (state) { | ||
params.set('state', state); | ||
} | ||
if (token) { | ||
params.set('token', token); | ||
} | ||
return `https://www.wix.com/installer/install?${params.toString()}`; | ||
}, | ||
@@ -115,7 +125,13 @@ async handleOAuthCallback(url, oauthOpts) { | ||
}, | ||
decodeJWT(token) { | ||
decodeJWT(token, verifyCallerClaims = false) { | ||
if (!opts.publicKey) { | ||
throw new Error('Missing public key. Make sure to pass it to the WixAppOAuthStrategy'); | ||
} | ||
const decoded = verify(token, opts.publicKey); | ||
const publicKey = parsePublicKeyIfEncoded(opts.publicKey); | ||
const decoded = verify(token, publicKey, verifyCallerClaims | ||
? { | ||
issuer: 'wix.com', | ||
audience: opts.appId, | ||
} | ||
: undefined); | ||
return { | ||
@@ -122,0 +138,0 @@ decoded, |
@@ -5,1 +5,2 @@ export declare const getDefaultContentHeader: (options: RequestInit | undefined) => { | ||
export declare const isObject: (val: any) => val is Object; | ||
export declare function parsePublicKeyIfEncoded(publicKey: string): string; |
@@ -12,1 +12,13 @@ // we follow a simplified version of the axios convention | ||
export const isObject = (val) => val && typeof val === 'object' && !Array.isArray(val); | ||
export function parsePublicKeyIfEncoded(publicKey) { | ||
if (publicKey.includes('\n') || publicKey.includes('\r')) { | ||
// publicKey is multi-line string, can be used as is | ||
return publicKey.trim(); | ||
} | ||
else { | ||
// publicKey is base64 encoded | ||
return typeof btoa !== 'undefined' | ||
? btoa(publicKey) | ||
: Buffer.from(publicKey, 'base64').toString('utf-8'); | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition } from '@wix/sdk-types'; | ||
import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition, SPIDefinition } from '@wix/sdk-types'; | ||
import { ConditionalExcept, EmptyObject } from 'type-fest'; | ||
@@ -70,3 +70,17 @@ import { AmbassadorFunctionDescriptor, BuildAmbassadorFunction } from './ambassador-modules.js'; | ||
}): Promise<ProcessedEvent<ExpectedEvents>>; | ||
apps: { | ||
AppInstalled: EventDefinition<{ | ||
appId: string; | ||
originInstanceId: string; | ||
}>; | ||
AppRemoved: EventDefinition<{ | ||
appId: string; | ||
}>; | ||
}; | ||
}; | ||
spi: <S extends SPIDefinition<any, any>>() => { | ||
process(jwt: string): S['__input']; | ||
processRequest(request: Request): Promise<S['__input']>; | ||
result(result: S['__result']): S['__result']; | ||
}; | ||
} & BuildDescriptors<T, H>; | ||
@@ -73,0 +87,0 @@ type ResolvePossibleEvents<T extends EventDefinition<any>[]> = { |
@@ -119,4 +119,35 @@ import { toHTTPModule, isAmbassadorModule, ambassadorModuleOptions, } from './ambassador-modules.js'; | ||
}, | ||
apps: { | ||
AppInstalled: { | ||
type: 'AppInstalled', | ||
__payload: void 0, | ||
}, | ||
AppRemoved: { | ||
type: 'AppRemoved', | ||
__payload: void 0, | ||
}, | ||
}, | ||
}, | ||
spi() { | ||
return { | ||
process(jwt) { | ||
if (!authStrategy.decodeJWT) { | ||
throw new Error('decodeJWT is not supported by the authentication strategy'); | ||
} | ||
const { decoded, valid } = authStrategy.decodeJWT(jwt, true); | ||
if (!valid) { | ||
throw new Error('JWT is not valid'); | ||
} | ||
return JSON.parse(decoded.data); | ||
}, | ||
async processRequest(request) { | ||
const body = await request.text(); | ||
return this.process(body); | ||
}, | ||
result(result) { | ||
return result; | ||
}, | ||
}; | ||
}, | ||
}; | ||
} |
import { AuthenticationStrategy } from '@wix/sdk-types'; | ||
export type WixAppOAuthStrategy = AuthenticationStrategy & { | ||
getInstallUrl({ redirectUrl }: { | ||
getInstallUrl(opts: { | ||
redirectUrl: string; | ||
state?: string; | ||
token?: string; | ||
}): string; | ||
@@ -21,3 +23,3 @@ handleOAuthCallback(url: string, opts?: { | ||
* @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API | ||
* @param opts.publicKey An optional public key for validating webhook requests | ||
* @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys) | ||
* @returns An authentication strategy that can be used with WixClient | ||
@@ -24,0 +26,0 @@ * @example |
@@ -5,2 +5,3 @@ "use strict"; | ||
const jsonwebtoken_1 = require("jsonwebtoken"); | ||
const helpers_js_1 = require("../helpers.js"); | ||
/** | ||
@@ -13,3 +14,3 @@ * Creates an authentication strategy for Wix Apps OAuth installation process. | ||
* @param opts.refreshToken An optional refresh token previously retrieved from Wix OAuth API | ||
* @param opts.publicKey An optional public key for validating webhook requests | ||
* @param opts.publicKey An optional public key for validating webhook requests (supports both PEM and base64 encoded keys) | ||
* @returns An authentication strategy that can be used with WixClient | ||
@@ -48,4 +49,13 @@ * @example | ||
return { | ||
getInstallUrl({ redirectUrl }) { | ||
return `https://www.wix.com/installer/install?appId=${opts.appId}&redirectUrl=${redirectUrl}`; | ||
getInstallUrl({ redirectUrl, token, state }) { | ||
const params = new URLSearchParams(); | ||
params.set('redirectUrl', redirectUrl); | ||
params.set('appId', opts.appId); | ||
if (state) { | ||
params.set('state', state); | ||
} | ||
if (token) { | ||
params.set('token', token); | ||
} | ||
return `https://www.wix.com/installer/install?${params.toString()}`; | ||
}, | ||
@@ -119,7 +129,13 @@ async handleOAuthCallback(url, oauthOpts) { | ||
}, | ||
decodeJWT(token) { | ||
decodeJWT(token, verifyCallerClaims = false) { | ||
if (!opts.publicKey) { | ||
throw new Error('Missing public key. Make sure to pass it to the WixAppOAuthStrategy'); | ||
} | ||
const decoded = (0, jsonwebtoken_1.verify)(token, opts.publicKey); | ||
const publicKey = (0, helpers_js_1.parsePublicKeyIfEncoded)(opts.publicKey); | ||
const decoded = (0, jsonwebtoken_1.verify)(token, publicKey, verifyCallerClaims | ||
? { | ||
issuer: 'wix.com', | ||
audience: opts.appId, | ||
} | ||
: undefined); | ||
return { | ||
@@ -126,0 +142,0 @@ decoded, |
@@ -5,1 +5,2 @@ export declare const getDefaultContentHeader: (options: RequestInit | undefined) => { | ||
export declare const isObject: (val: any) => val is Object; | ||
export declare function parsePublicKeyIfEncoded(publicKey: string): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isObject = exports.getDefaultContentHeader = void 0; | ||
exports.parsePublicKeyIfEncoded = exports.isObject = exports.getDefaultContentHeader = void 0; | ||
// we follow a simplified version of the axios convention | ||
@@ -17,1 +17,14 @@ // https://github.com/axios/axios/blob/649d739288c8e2c55829ac60e2345a0f3439c730/lib/defaults/index.js#L65 | ||
exports.isObject = isObject; | ||
function parsePublicKeyIfEncoded(publicKey) { | ||
if (publicKey.includes('\n') || publicKey.includes('\r')) { | ||
// publicKey is multi-line string, can be used as is | ||
return publicKey.trim(); | ||
} | ||
else { | ||
// publicKey is base64 encoded | ||
return typeof btoa !== 'undefined' | ||
? btoa(publicKey) | ||
: Buffer.from(publicKey, 'base64').toString('utf-8'); | ||
} | ||
} | ||
exports.parsePublicKeyIfEncoded = parsePublicKeyIfEncoded; |
@@ -1,2 +0,2 @@ | ||
import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition } from '@wix/sdk-types'; | ||
import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildRESTFunction, Host, HostModule, HostModuleAPI, RESTFunctionDescriptor, EventDefinition, SPIDefinition } from '@wix/sdk-types'; | ||
import { ConditionalExcept, EmptyObject } from 'type-fest'; | ||
@@ -70,3 +70,17 @@ import { AmbassadorFunctionDescriptor, BuildAmbassadorFunction } from './ambassador-modules.js'; | ||
}): Promise<ProcessedEvent<ExpectedEvents>>; | ||
apps: { | ||
AppInstalled: EventDefinition<{ | ||
appId: string; | ||
originInstanceId: string; | ||
}>; | ||
AppRemoved: EventDefinition<{ | ||
appId: string; | ||
}>; | ||
}; | ||
}; | ||
spi: <S extends SPIDefinition<any, any>>() => { | ||
process(jwt: string): S['__input']; | ||
processRequest(request: Request): Promise<S['__input']>; | ||
result(result: S['__result']): S['__result']; | ||
}; | ||
} & BuildDescriptors<T, H>; | ||
@@ -73,0 +87,0 @@ type ResolvePossibleEvents<T extends EventDefinition<any>[]> = { |
@@ -122,5 +122,36 @@ "use strict"; | ||
}, | ||
apps: { | ||
AppInstalled: { | ||
type: 'AppInstalled', | ||
__payload: void 0, | ||
}, | ||
AppRemoved: { | ||
type: 'AppRemoved', | ||
__payload: void 0, | ||
}, | ||
}, | ||
}, | ||
spi() { | ||
return { | ||
process(jwt) { | ||
if (!authStrategy.decodeJWT) { | ||
throw new Error('decodeJWT is not supported by the authentication strategy'); | ||
} | ||
const { decoded, valid } = authStrategy.decodeJWT(jwt, true); | ||
if (!valid) { | ||
throw new Error('JWT is not valid'); | ||
} | ||
return JSON.parse(decoded.data); | ||
}, | ||
async processRequest(request) { | ||
const body = await request.text(); | ||
return this.process(body); | ||
}, | ||
result(result) { | ||
return result; | ||
}, | ||
}; | ||
}, | ||
}; | ||
} | ||
exports.createClient = createClient; |
{ | ||
"name": "@wix/sdk", | ||
"version": "1.7.2", | ||
"version": "1.7.3", | ||
"license": "UNLICENSED", | ||
@@ -65,3 +65,3 @@ "author": { | ||
"@wix/redirects": "^1.0.32", | ||
"@wix/sdk-types": "^1.5.5", | ||
"@wix/sdk-types": "^1.5.6", | ||
"crypto-js": "^4.2.0", | ||
@@ -82,6 +82,7 @@ "jsonwebtoken": "^9.0.2", | ||
"@vitest/ui": "^1.1.3", | ||
"@wix/ecom": "^1.0.473", | ||
"@wix/events": "^1.0.144", | ||
"@wix/ecom": "^1.0.474", | ||
"@wix/events": "^1.0.145", | ||
"@wix/metro": "^1.0.73", | ||
"@wix/metro-runtime": "^1.1616.0", | ||
"@wix/metro-runtime": "^1.1618.0", | ||
"@wix/sdk-runtime": "0.2.7", | ||
"eslint": "^8.56.0", | ||
@@ -120,3 +121,3 @@ "eslint-config-sdk": "0.0.0", | ||
}, | ||
"falconPackageHash": "c93d4242558d1559e8e7149680612d8aca349adb52ef06a00050f11d" | ||
"falconPackageHash": "1ab723e4b75dc05738d9710385e9cfbe6d32deae3902e5809011288c" | ||
} |
139177
4.31%3453
4.64%19
5.56%Updated