@wix/api-client
Advanced tools
Comparing version 1.11.1 to 1.12.0
@@ -21,2 +21,3 @@ import { AuthenticationStrategy } from '@wix/sdk-types'; | ||
}>; | ||
elevated(): Promise<AppStrategy>; | ||
}; | ||
@@ -23,0 +24,0 @@ /** |
@@ -188,2 +188,34 @@ import { parsePublicKeyIfEncoded } from '../helpers.js'; | ||
}, | ||
async elevated() { | ||
if ('accessToken' in opts && opts.accessToken) { | ||
const tokenInfoRes = await fetch('https://www.wixapis.com/oauth2/token-info', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
token: opts.accessToken, | ||
}), | ||
}); | ||
if (tokenInfoRes.status !== 200) { | ||
throw new Error(`Failed to get token info. Unexpected status code from Wix OAuth API: ${tokenInfoRes.status}`); | ||
} | ||
const tokenInfo = await tokenInfoRes.json(); | ||
if (tokenInfo.app_id !== opts.appId) { | ||
throw new Error(`Invalid access token. The token is not issued for the app with ID "${opts.appId}"`); | ||
} | ||
if (!tokenInfo.instanceId) { | ||
throw new Error('Unexpected token info. The token does not contain instance ID'); | ||
} | ||
return AppStrategy({ | ||
appId: opts.appId, | ||
appSecret: opts.appSecret, | ||
publicKey: opts.publicKey, | ||
instanceId: tokenInfo.instanceId, | ||
}); | ||
} | ||
else { | ||
throw new Error('Providing an access token is required to perform elevation. Make sure to pass it to the AppStrategy'); | ||
} | ||
}, | ||
async decodeJWT(token, verifyCallerClaims = false) { | ||
@@ -190,0 +222,0 @@ if (!opts.publicKey) { |
@@ -69,2 +69,14 @@ import { authentication } from '@wix/identity'; | ||
loggedIn: () => boolean; | ||
/** | ||
* Retrieves and authenticates site member's access and refresh tokens given a member ID. | ||
* A member ID for external login can be retrieved from the Wix Members API using `queryMembers` | ||
* function, using any externally identifiable field (e.g. email, phone number, etc.). | ||
* | ||
* In addition to the member ID, an API Key with permissions on Wix Contacts & Members is required | ||
* (this is an administrative API that bypasses the need for a session token and so can only be used | ||
* from confidential clients). | ||
* @param memberId The member ID to get the tokens for | ||
* @param apiKey An API Key with permissions on Wix Contacts & Members | ||
* @returns Tokens (access and refresh) for the member | ||
*/ | ||
getMemberTokensForExternalLogin: (memberId: string, apiKey: string) => Promise<Tokens>; | ||
@@ -71,0 +83,0 @@ } |
@@ -36,3 +36,5 @@ import { AuthenticationStrategy, BoundAuthenticationStrategy, BuildDescriptors, Descriptors, EventDefinition, EventIdentity, Host, HostModule, RESTFunctionDescriptor, ServicePluginContract, ServicePluginDefinition } from '@wix/sdk-types'; | ||
use<R extends Descriptors = EmptyObject>(modules: H extends Host<any> ? AssertHostMatches<R, H> : R): BuildDescriptors<R, H>; | ||
enableContext(contextType: ContextType): void; | ||
enableContext(contextType: ContextType, opts?: { | ||
elevated: boolean; | ||
}): void; | ||
graphql<Result, Variables>(query: string | ((string | String) & TypedQueryInput<Result, Variables>), variables?: Variables): Promise<{ | ||
@@ -50,2 +52,5 @@ data: Result; | ||
}): Promise<ProcessedEvent<ExpectedEvents>>; | ||
parseJWT(jwt: string): Promise<ProcessedEvent>; | ||
parseRequest(request: Request): Promise<ProcessedEvent>; | ||
executeHandlers(event: ProcessedEvent): Promise<void>; | ||
apps: { | ||
@@ -71,2 +76,5 @@ AppInstalled: EventDefinition<{ | ||
processRequest(request: Request): Promise<Response>; | ||
parseJWT(jwt: string): Promise<unknown>; | ||
parseRequest(request: Request): Promise<unknown>; | ||
executeHandler(servicePluginRequest: ProcessedEvent): Promise<void>; | ||
}; | ||
@@ -73,0 +81,0 @@ } & BuildDescriptors<T, H>; |
@@ -98,13 +98,28 @@ import { wixContext } from '@wix/sdk-context'; | ||
use, | ||
enableContext(contextType) { | ||
enableContext(contextType, opts = { elevated: false }) { | ||
if (contextType === 'global') { | ||
if (globalThis.__wix_context__ != null) { | ||
globalThis.__wix_context__.client = this; | ||
if (opts.elevated) { | ||
globalThis.__wix_context__.elevatedClient = this; | ||
} | ||
else { | ||
globalThis.__wix_context__.client = this; | ||
} | ||
} | ||
else { | ||
globalThis.__wix_context__ = { client: this }; | ||
if (opts.elevated) { | ||
globalThis.__wix_context__ = { elevatedClient: this }; | ||
} | ||
else { | ||
globalThis.__wix_context__ = { client: this }; | ||
} | ||
} | ||
} | ||
else { | ||
wixContext.client = this; | ||
if (opts.elevated) { | ||
wixContext.elevatedClient = this; | ||
} | ||
else { | ||
wixContext.client = this; | ||
} | ||
} | ||
@@ -153,22 +168,6 @@ }, | ||
getRegisteredEvents: () => Array.from(eventHandlers.keys()), | ||
process: async (jwt, opts = { | ||
async process(jwt, opts = { | ||
expectedEvents: [], | ||
}) => { | ||
if (!authStrategy.decodeJWT) { | ||
throw new Error('decodeJWT is not supported by the authentication strategy'); | ||
} | ||
const { decoded, valid } = await authStrategy.decodeJWT(jwt); | ||
if (!valid) { | ||
throw new Error('JWT is not valid'); | ||
} | ||
if (typeof decoded.data !== 'string') { | ||
throw new Error(`Unexpected type of JWT data: expected string, got ${typeof decoded.data}`); | ||
} | ||
const parsedDecoded = JSON.parse(decoded.data); | ||
const eventType = parsedDecoded.eventType; | ||
const instanceId = parsedDecoded.instanceId; | ||
const identity = parsedDecoded.identity | ||
? JSON.parse(parsedDecoded.identity) | ||
: undefined; | ||
const payload = JSON.parse(parsedDecoded.data); | ||
}) { | ||
const { eventType, identity, instanceId, payload } = await this.parseJWT(jwt); | ||
const allExpectedEvents = [ | ||
@@ -200,2 +199,45 @@ ...opts.expectedEvents, | ||
}, | ||
async parseJWT(jwt) { | ||
if (!authStrategy.decodeJWT) { | ||
throw new Error('decodeJWT is not supported by the authentication strategy'); | ||
} | ||
const { decoded, valid } = await authStrategy.decodeJWT(jwt); | ||
if (!valid) { | ||
throw new Error('JWT is not valid'); | ||
} | ||
if (typeof decoded.data !== 'string') { | ||
throw new Error(`Unexpected type of JWT data: expected string, got ${typeof decoded.data}`); | ||
} | ||
const parsedDecoded = JSON.parse(decoded.data); | ||
const eventType = parsedDecoded.eventType; | ||
const instanceId = parsedDecoded.instanceId; | ||
const identity = parsedDecoded.identity | ||
? JSON.parse(parsedDecoded.identity) | ||
: undefined; | ||
const payload = JSON.parse(parsedDecoded.data); | ||
return { | ||
instanceId, | ||
eventType, | ||
payload, | ||
identity, | ||
}; | ||
}, | ||
async parseRequest(request) { | ||
const jwt = await request.text(); | ||
return this.parseJWT(jwt); | ||
}, | ||
async executeHandlers(event) { | ||
const allExpectedEvents = Array.from(eventHandlers.keys()).map((type) => ({ type })); | ||
if (allExpectedEvents.length > 0 && | ||
!allExpectedEvents.some(({ type }) => type === event.eventType)) { | ||
throw new Error(`Unexpected event type: ${event.eventType}. Expected one of: ${allExpectedEvents | ||
.map((x) => x.type) | ||
.join(', ')}`); | ||
} | ||
const handlers = eventHandlers.get(event.eventType) ?? []; | ||
await Promise.all(handlers.map(({ eventDefinition, handler }) => runHandler(eventDefinition, handler, event.payload, { | ||
instanceId: event.instanceId, | ||
identity: event.identity, | ||
}))); | ||
}, | ||
apps: { | ||
@@ -209,6 +251,16 @@ AppInstalled: EventDefinition('AppInstalled')(), | ||
async process(request) { | ||
const servicePluginRequest = await this.parseJWT(request.body); | ||
return this.executeHandler(servicePluginRequest, request.url); | ||
}, | ||
async processRequest(request) { | ||
const url = request.url; | ||
const body = await request.text(); | ||
const implMethodResult = await this.process({ url, body }); | ||
return Response.json(implMethodResult); | ||
}, | ||
async parseJWT(jwt) { | ||
if (!authStrategy.decodeJWT) { | ||
throw new Error('decodeJWT is not supported by the authentication strategy'); | ||
} | ||
const { decoded, valid } = await authStrategy.decodeJWT(request.body, true); | ||
const { decoded, valid } = await authStrategy.decodeJWT(jwt, true); | ||
if (!valid) { | ||
@@ -226,3 +278,6 @@ throw new Error('JWT is not valid'); | ||
} | ||
const componentType = decoded.data?.metadata.appExtensionType.toLowerCase(); | ||
return decoded.data; | ||
}, | ||
async executeHandler(servicePluginRequest, url) { | ||
const componentType = servicePluginRequest.metadata.appExtensionType.toLowerCase(); | ||
const implementations = servicePluginsImplementations.get(componentType) ?? []; | ||
@@ -236,6 +291,5 @@ if (implementations.length === 0) { | ||
const { implementation: impl, servicePluginDefinition } = implementations[0]; | ||
const method = servicePluginDefinition.methods.find((m) => request.url.endsWith(m.primaryHttpMappingPath)); | ||
const method = servicePluginDefinition.methods.find((m) => url.endsWith(m.primaryHttpMappingPath)); | ||
if (!method) { | ||
throw new Error('Unexpect request: request url did not match any method: ' + | ||
request.url); | ||
throw new Error('Unexpect request: request url did not match any method: ' + url); | ||
} | ||
@@ -246,12 +300,6 @@ const implMethod = impl[method.name]; | ||
} | ||
return method.transformations.toREST(await implMethod(method.transformations.fromREST(decoded.data))); | ||
return method.transformations.toREST(await implMethod(method.transformations.fromREST(servicePluginRequest))); | ||
}, | ||
async processRequest(request) { | ||
const url = request.url; | ||
const body = await request.text(); | ||
const implMethodResult = await this.process({ url, body }); | ||
return Response.json(implMethodResult); | ||
}, | ||
}, | ||
}; | ||
} |
{ | ||
"name": "@wix/api-client", | ||
"version": "1.11.1", | ||
"version": "1.12.0", | ||
"license": "UNLICENSED", | ||
@@ -25,6 +25,6 @@ "main": "build/index.js", | ||
"@wix/identity": "^1.0.78", | ||
"@wix/image-kit": "^1.70.0", | ||
"@wix/image-kit": "^1.71.0", | ||
"@wix/redirects": "^1.0.41", | ||
"@wix/sdk-context": "^0.0.1", | ||
"@wix/sdk-runtime": "0.3.0", | ||
"@wix/sdk-runtime": "0.3.2", | ||
"@wix/sdk-types": "^1.9.0", | ||
@@ -39,3 +39,3 @@ "crypto-js": "^4.2.0", | ||
"@wix/metro-runtime": "^1.1677.0", | ||
"@wix/sdk": "1.11.1" | ||
"@wix/sdk": "1.12.0" | ||
}, | ||
@@ -53,3 +53,3 @@ "wix": { | ||
}, | ||
"falconPackageHash": "c3a0e71dc79f3729303f0f9c761ddc33874616c7c0988e164d05eabc" | ||
"falconPackageHash": "f33e506f0b9bcffbbafe855edba84ab7fad9b84a35450512d0e9357a" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83820
2046
8
+ Added@wix/sdk-runtime@0.3.2(transitive)
- Removed@wix/sdk-runtime@0.3.0(transitive)
Updated@wix/image-kit@^1.71.0
Updated@wix/sdk-runtime@0.3.2