@wix/astro 1.0.16 → 1.0.18

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.
Files changed (40) hide show
  1. package/build/index.d.ts +3 -1
  2. package/build/index.js +62 -10
  3. package/build/index.js.map +1 -1
  4. package/build-browser-runtime/{chunk-HJBVRKIZ.js → setup.js} +13 -5
  5. package/build-runtime/chunk-C3QOE2TZ.js +7 -0
  6. package/build-runtime/chunk-HVACFX6T.js +18 -0
  7. package/build-runtime/chunk-UZPSWWI5.js +13 -0
  8. package/build-runtime/chunk-YMZMZCBN.js +4063 -0
  9. package/build-runtime/context/non-elevated.js +26 -14
  10. package/build-runtime/middleware/auth.js +6 -18
  11. package/build-runtime/routes/auth/callback.d.ts +5 -0
  12. package/build-runtime/routes/auth/callback.js +48 -0
  13. package/build-runtime/routes/auth/login.d.ts +5 -0
  14. package/build-runtime/routes/auth/login.js +38 -0
  15. package/build-runtime/routes/auth/logout-callback.d.ts +5 -0
  16. package/build-runtime/routes/auth/logout-callback.js +20 -0
  17. package/build-runtime/routes/auth/logout.d.ts +5 -0
  18. package/build-runtime/routes/auth/logout.js +17 -0
  19. package/package.json +8 -6
  20. package/src/constants.ts +2 -0
  21. package/src/context/non-elevated.ts +31 -9
  22. package/src/context/setup.ts +14 -0
  23. package/src/context/utils.ts +0 -4
  24. package/src/directories.ts +1 -1
  25. package/src/env.d.ts +2 -0
  26. package/src/index.ts +48 -4
  27. package/src/plugins/setupSsrContext.ts +9 -7
  28. package/src/routes/auth/callback.ts +49 -0
  29. package/src/routes/auth/login.ts +35 -0
  30. package/src/routes/auth/logout-callback.ts +16 -0
  31. package/src/routes/auth/logout.ts +14 -0
  32. package/src/utils/contextualAuth.ts +4 -0
  33. package/src/utils/writeVirtualBackofficeExtensionFiles.ts +18 -2
  34. package/tsup.config.mjs +13 -7
  35. package/build-browser-runtime/before-hydration.js +0 -24
  36. package/build-browser-runtime/page.d.ts +0 -5
  37. package/build-browser-runtime/page.js +0 -14
  38. package/src/context/before-hydration.ts +0 -21
  39. package/src/context/page.ts +0 -7
  40. /package/build-browser-runtime/{before-hydration.d.ts → setup.d.ts} +0 -0
@@ -1,20 +1,32 @@
1
+ import {
2
+ authAsyncLocalStorage
3
+ } from "../chunk-C3QOE2TZ.js";
4
+
1
5
  // src/context/non-elevated.ts
2
6
  import { createClient, OAuthStrategy } from "@wix/sdk";
3
7
  import { WIX_CLIENT_ID } from "astro:env/client";
4
-
5
- // src/utils/authAsyncLocalStorage.ts
6
- import { AsyncLocalStorage } from "node:async_hooks";
7
- var authAsyncLocalStorage = new AsyncLocalStorage();
8
-
9
- // src/context/non-elevated.ts
10
- var contextClient = createClient({
11
- get auth() {
12
- const store = authAsyncLocalStorage.getStore();
13
- const auth = OAuthStrategy({
14
- clientId: WIX_CLIENT_ID,
15
- tokens: store?.sessionTokens?.tokens
16
- });
17
- return auth;
8
+ var authProxy = new Proxy(
9
+ {},
10
+ {
11
+ get(target, prop) {
12
+ const auth = OAuthStrategy({
13
+ clientId: WIX_CLIENT_ID
14
+ });
15
+ const value = auth[prop];
16
+ if (typeof value !== "function") {
17
+ return value;
18
+ }
19
+ return function(...args) {
20
+ const store = authAsyncLocalStorage.getStore();
21
+ if (store?.sessionTokens) {
22
+ auth.setTokens(store.sessionTokens.tokens);
23
+ }
24
+ return value.apply(auth, args);
25
+ };
26
+ }
18
27
  }
28
+ );
29
+ var contextClient = createClient({
30
+ auth: authProxy
19
31
  });
20
32
  contextClient.enableContext("global");
@@ -1,6 +1,9 @@
1
- // src/utils/authAsyncLocalStorage.ts
2
- import { AsyncLocalStorage } from "node:async_hooks";
3
- var authAsyncLocalStorage = new AsyncLocalStorage();
1
+ import {
2
+ authAsyncLocalStorage
3
+ } from "../chunk-C3QOE2TZ.js";
4
+ import {
5
+ saveSessionTokensToCookie
6
+ } from "../chunk-HVACFX6T.js";
4
7
 
5
8
  // src/utils/generateVisitorTokens.ts
6
9
  import { OAuthStrategy } from "@wix/sdk";
@@ -42,21 +45,6 @@ function getSessionTokensFromCookie(context) {
42
45
  return null;
43
46
  }
44
47
 
45
- // src/utils/saveSessionTokensToCookie.ts
46
- import { WIX_CLIENT_ID as WIX_CLIENT_ID3 } from "astro:env/client";
47
- function sessionCookieJson(tokens) {
48
- return {
49
- clientId: WIX_CLIENT_ID3,
50
- tokens
51
- };
52
- }
53
- function saveSessionTokensToCookie(context, tokens) {
54
- context.cookies.set("wixSession", sessionCookieJson(tokens), {
55
- path: "/",
56
- secure: true
57
- });
58
- }
59
-
60
48
  // src/middleware/auth.ts
61
49
  var onRequest = async (context, next) => {
62
50
  const store = {
@@ -0,0 +1,5 @@
1
+ import { APIContext } from 'astro';
2
+
3
+ declare function GET(context: APIContext): Promise<Response>;
4
+
5
+ export { GET };
@@ -0,0 +1,48 @@
1
+ import {
2
+ saveSessionTokensToCookie
3
+ } from "../../chunk-HVACFX6T.js";
4
+ import {
5
+ z
6
+ } from "../../chunk-YMZMZCBN.js";
7
+ import {
8
+ auth,
9
+ oAuthStateCookieName
10
+ } from "../../chunk-UZPSWWI5.js";
11
+
12
+ // src/routes/auth/callback.ts
13
+ var oauthCookieSchema = z.object({
14
+ codeChallenge: z.string(),
15
+ codeVerifier: z.string(),
16
+ originalUri: z.string(),
17
+ redirectUri: z.string(),
18
+ state: z.string()
19
+ });
20
+ async function GET(context) {
21
+ const oauthStateCookie = context.cookies.get(oAuthStateCookieName);
22
+ if (oauthStateCookie == null) {
23
+ throw new Error(`Missing \`${oAuthStateCookieName}\` cookie`);
24
+ }
25
+ const oauthData = oauthCookieSchema.parse(JSON.parse(oauthStateCookie.value));
26
+ if (!oauthData.originalUri.startsWith("/")) {
27
+ throw new Error("Invalid `originalUri` cookie param");
28
+ }
29
+ const { code, error, errorDescription, state } = auth.parseFromUrl(
30
+ context.url.toString(),
31
+ "query"
32
+ );
33
+ if (error != null) {
34
+ throw new Error(`Error while authenticating: \`${errorDescription}\``);
35
+ }
36
+ const memberTokens = await auth.getMemberTokens(code, state, oauthData);
37
+ context.cookies.delete(oAuthStateCookieName, {
38
+ httpOnly: true,
39
+ path: "/",
40
+ sameSite: "lax",
41
+ secure: true
42
+ });
43
+ saveSessionTokensToCookie(context, memberTokens);
44
+ return context.redirect(oauthData.originalUri);
45
+ }
46
+ export {
47
+ GET
48
+ };
@@ -0,0 +1,5 @@
1
+ import { APIContext } from 'astro';
2
+
3
+ declare function GET({ url }: APIContext): Promise<Response>;
4
+
5
+ export { GET };
@@ -0,0 +1,38 @@
1
+ import {
2
+ z
3
+ } from "../../chunk-YMZMZCBN.js";
4
+ import {
5
+ auth,
6
+ oAuthStateCookieName
7
+ } from "../../chunk-UZPSWWI5.js";
8
+
9
+ // src/routes/auth/login.ts
10
+ var loginSearchParams = z.object({
11
+ prompt: z.enum(["login", "none"]).optional(),
12
+ returnToUrl: z.string().optional()
13
+ });
14
+ async function GET({ url }) {
15
+ const { prompt, returnToUrl } = loginSearchParams.parse(
16
+ Object.fromEntries(url.searchParams.entries())
17
+ );
18
+ const oauthData = auth.generateOAuthData(
19
+ new URL("/api/auth/callback", url).toString(),
20
+ returnToUrl
21
+ );
22
+ const { authUrl } = await auth.getAuthUrl(oauthData, {
23
+ prompt,
24
+ responseMode: "query"
25
+ });
26
+ return new Response(null, {
27
+ headers: {
28
+ Location: authUrl,
29
+ "Set-Cookie": `${oAuthStateCookieName}=${JSON.stringify(
30
+ oauthData
31
+ )}; Max-Age=1800; Path=/; HttpOnly; Secure; SameSite=Lax`
32
+ },
33
+ status: 302
34
+ });
35
+ }
36
+ export {
37
+ GET
38
+ };
@@ -0,0 +1,5 @@
1
+ import { APIRoute } from 'astro';
2
+
3
+ declare const GET: APIRoute;
4
+
5
+ export { GET };
@@ -0,0 +1,20 @@
1
+ import {
2
+ saveSessionTokensToCookie
3
+ } from "../../chunk-HVACFX6T.js";
4
+ import {
5
+ auth,
6
+ returnToQueryParamName
7
+ } from "../../chunk-UZPSWWI5.js";
8
+
9
+ // src/routes/auth/logout-callback.ts
10
+ var GET = async (context) => {
11
+ const returnTo = context.url.searchParams.get(returnToQueryParamName) ?? "/";
12
+ if (!returnTo.startsWith("/")) {
13
+ throw new Error(`Invalid \`${returnToQueryParamName}\` query param`);
14
+ }
15
+ saveSessionTokensToCookie(context, await auth.generateVisitorTokens());
16
+ return context.redirect(returnTo);
17
+ };
18
+ export {
19
+ GET
20
+ };
@@ -0,0 +1,5 @@
1
+ import { APIContext } from 'astro';
2
+
3
+ declare function POST({ redirect, request }: APIContext): Promise<Response>;
4
+
5
+ export { POST };
@@ -0,0 +1,17 @@
1
+ import {
2
+ auth,
3
+ returnToQueryParamName
4
+ } from "../../chunk-UZPSWWI5.js";
5
+
6
+ // src/routes/auth/logout.ts
7
+ async function POST({ redirect, request }) {
8
+ const returnTo = request.headers.get("Referer") ?? "/";
9
+ const baseUrl = `${new URL(request.url).origin}/${import.meta.env.BASE_URL}`;
10
+ const postFlowUrl = new URL("/api/auth/logout-callback", baseUrl);
11
+ postFlowUrl.searchParams.set(returnToQueryParamName, returnTo);
12
+ const { logoutUrl } = await auth.logout(postFlowUrl.toString());
13
+ return redirect(logoutUrl);
14
+ }
15
+ export {
16
+ POST
17
+ };
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@wix/astro",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "devDependencies": {
5
5
  "@wix/dashboard": "^1.3.35",
6
- "@wix/sdk": "^1.15.17",
6
+ "@wix/essentials": "^0.1.23",
7
+ "@wix/sdk": "^1.15.23",
8
+ "@wix/sdk-context": "^0.0.1",
7
9
  "astro": "^5.7.4",
8
10
  "chalk": "^5.4.1",
9
11
  "chokidar": "^3.6.0",
@@ -17,12 +19,12 @@
17
19
  },
18
20
  "exports": {
19
21
  ".": "./build/index.js",
20
- "./context/before-hydration": "./build-browser-runtime/before-hydration.js",
21
- "./context/page": "./build-browser-runtime/page.js"
22
+ "./context/setup": "./build-browser-runtime/setup.js"
22
23
  },
23
24
  "peerDependencies": {
24
25
  "@wix/dashboard": "^1.3.35",
25
- "@wix/sdk": "^1.15.17",
26
+ "@wix/essentials": "^0.1.23",
27
+ "@wix/sdk": "^1.15.23",
26
28
  "astro": "^5.0.0"
27
29
  },
28
30
  "publishConfig": {
@@ -46,5 +48,5 @@
46
48
  ]
47
49
  }
48
50
  },
49
- "falconPackageHash": "6148e131e45c16f42c1c8b3fa4778e5d51ffc096a593673996084c97"
51
+ "falconPackageHash": "f4b9fa1e979f7c356f0c70b13e628a4056b3205c3cbcbde60c7005de"
50
52
  }
@@ -0,0 +1,2 @@
1
+ export const oAuthStateCookieName = 'oAuthState';
2
+ export const returnToQueryParamName = 'returnTo';
@@ -1,18 +1,40 @@
1
+ import type { IOAuthStrategy } from '@wix/sdk';
1
2
  import { createClient, OAuthStrategy } from '@wix/sdk';
2
3
  import { WIX_CLIENT_ID } from 'astro:env/client';
3
4
  import { authAsyncLocalStorage } from '../utils/authAsyncLocalStorage.js';
4
5
 
5
- const contextClient = createClient({
6
- get auth() {
7
- const store = authAsyncLocalStorage.getStore();
6
+ const authProxy = new Proxy(
7
+ {},
8
+ {
9
+ get(target, prop) {
10
+ const auth = OAuthStrategy({
11
+ clientId: WIX_CLIENT_ID,
12
+ });
13
+
14
+ const value = auth[prop as keyof typeof auth];
15
+
16
+ if (typeof value !== 'function') {
17
+ return value;
18
+ }
8
19
 
9
- const auth = OAuthStrategy({
10
- clientId: WIX_CLIENT_ID,
11
- tokens: store?.sessionTokens?.tokens,
12
- });
20
+ // it's important that the store is accessed only when the middleware has a chance
21
+ // to set the async local storage
22
+ return function (...args: unknown[]) {
23
+ const store = authAsyncLocalStorage.getStore();
13
24
 
14
- return auth;
15
- },
25
+ if (store?.sessionTokens) {
26
+ auth.setTokens(store.sessionTokens.tokens);
27
+ }
28
+
29
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
30
+ return (value as Function).apply(auth, args);
31
+ };
32
+ },
33
+ }
34
+ ) as IOAuthStrategy;
35
+
36
+ const contextClient = createClient({
37
+ auth: authProxy,
16
38
  });
17
39
 
18
40
  contextClient.enableContext('global');
@@ -0,0 +1,14 @@
1
+ import { wixContext } from '@wix/sdk-context';
2
+ import { getSessionClient } from './utils.js';
3
+
4
+ export function setup(options: { clientId: string }) {
5
+ // check untyped global context which may be necessary if
6
+ // both `page` and `before-hydration` hooks have been loaded together
7
+ if (wixContext.client != null) {
8
+ return;
9
+ }
10
+
11
+ if (!location.pathname.startsWith('/_wix/extensions/backoffice')) {
12
+ getSessionClient(options).enableContext('module');
13
+ }
14
+ }
@@ -1,10 +1,6 @@
1
1
  import { createClient } from '@wix/sdk';
2
2
  import { SiteSessionAuth } from '@wix/sdk/auth/site-session';
3
3
 
4
- export const isBackofficeExtension = location.pathname.startsWith(
5
- '/_wix/extensions/backoffice'
6
- );
7
-
8
4
  function getCookieAsJson(name: string) {
9
5
  const cookies = document.cookie.split('; ');
10
6
  const cookie = cookies.find((row) => row.startsWith(`${name}=`));
@@ -1,5 +1,5 @@
1
1
  import { join } from 'node:path';
2
2
 
3
- export const SRC_DIR = 'src';
3
+ const SRC_DIR = 'src';
4
4
  export const GIT_IGNORED_DIR = '.wix';
5
5
  export const EXTENSIONS_DIR = join(SRC_DIR, 'extensions');
package/src/env.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /// <reference types="astro/env" />
2
+
1
3
  declare module 'astro:env/client' {
2
4
  export const WIX_CLIENT_ID: string;
3
5
  }
package/src/index.ts CHANGED
@@ -20,7 +20,13 @@ import { writeVirtualBackofficeExtensionFiles } from './utils/writeVirtualBackof
20
20
  import { writeVirtualServicePluginExtensionFiles } from './utils/writeVirtualServicePluginExtensionFiles.js';
21
21
  import { writeVirtualWebhookExtensionFiles } from './utils/writeVirtualWebhookExtensionFiles.js';
22
22
 
23
- const createIntegration = (): AstroIntegration => {
23
+ const createIntegration = (
24
+ options: {
25
+ enableAuthRoutes?: boolean;
26
+ } = {
27
+ enableAuthRoutes: true,
28
+ }
29
+ ): AstroIntegration => {
24
30
  let _config: AstroConfig;
25
31
  let model: Model | null = null;
26
32
 
@@ -67,7 +73,7 @@ const createIntegration = (): AstroIntegration => {
67
73
  'before-hydration',
68
74
  outdent`
69
75
  import { WIX_CLIENT_ID } from 'astro:env/client';
70
- import { setup } from '@wix/astro/context/before-hydration';
76
+ import { setup } from '@wix/astro/context/setup';
71
77
 
72
78
  setup({ clientId: WIX_CLIENT_ID });
73
79
  `
@@ -77,7 +83,7 @@ const createIntegration = (): AstroIntegration => {
77
83
  'page',
78
84
  outdent`
79
85
  import { WIX_CLIENT_ID } from 'astro:env/client';
80
- import { setup } from '@wix/astro/context/page';
86
+ import { setup } from '@wix/astro/context/setup';
81
87
 
82
88
  setup({ clientId: WIX_CLIENT_ID });
83
89
  `
@@ -121,11 +127,49 @@ const createIntegration = (): AstroIntegration => {
121
127
  plugins: [
122
128
  patchGlobal(),
123
129
  patchAstroInlineScripts(),
124
- setupSsrContext(rootDir),
130
+ setupSsrContext(),
125
131
  ],
126
132
  },
127
133
  });
128
134
 
135
+ if (options.enableAuthRoutes) {
136
+ injectRoute({
137
+ entrypoint: new URL(
138
+ '../build-runtime/routes/auth/login.js',
139
+ import.meta.url
140
+ ),
141
+ pattern: '/api/auth/login',
142
+ prerender: false,
143
+ });
144
+
145
+ injectRoute({
146
+ entrypoint: new URL(
147
+ '../build-runtime/routes/auth/logout.js',
148
+ import.meta.url
149
+ ),
150
+ pattern: '/api/auth/logout',
151
+ prerender: false,
152
+ });
153
+
154
+ injectRoute({
155
+ entrypoint: new URL(
156
+ '../build-runtime/routes/auth/callback.js',
157
+ import.meta.url
158
+ ),
159
+ pattern: '/api/auth/callback',
160
+ prerender: false,
161
+ });
162
+
163
+ injectRoute({
164
+ entrypoint: new URL(
165
+ '../build-runtime/routes/auth/logout-callback.js',
166
+ import.meta.url
167
+ ),
168
+ pattern: '/api/auth/logout-callback',
169
+ prerender: false,
170
+ });
171
+ }
172
+
129
173
  // add support for webhook extensions
130
174
  const webhookCodegenDir = join(codegenDir, 'extensions/webhooks');
131
175
  await outputDir(webhookCodegenDir);
@@ -1,11 +1,8 @@
1
1
  import { extname, join } from 'node:path';
2
2
  import type { PluginOption } from 'vite';
3
3
  import { outdent } from 'outdent';
4
- import { SRC_DIR } from '../directories.js';
5
-
6
- export function setupSsrContext(rootDir: string): PluginOption {
7
- const srcDir = join(rootDir, SRC_DIR);
8
4
 
5
+ export function setupSsrContext(): PluginOption {
9
6
  const nonElevatedSetupUrl = new URL(
10
7
  '../build-runtime/context/non-elevated.js',
11
8
  import.meta.url
@@ -21,12 +18,17 @@ export function setupSsrContext(rootDir: string): PluginOption {
21
18
  },
22
19
  name: 'setup-ssr-context',
23
20
  transform(code, id) {
24
- if (!id.startsWith(srcDir)) {
21
+ const extension = extname(id);
22
+
23
+ if (
24
+ // ignore node_modules
25
+ id.includes('node_modules') &&
26
+ // but allow injected runtime
27
+ !id.includes(join('node_modules', '@wix', 'astro'))
28
+ ) {
25
29
  return null;
26
30
  }
27
31
 
28
- const extension = extname(id);
29
-
30
32
  if (
31
33
  extension !== '.js' &&
32
34
  extension !== '.astro' &&
@@ -0,0 +1,49 @@
1
+ import type { APIContext } from 'astro';
2
+ import { z } from 'zod';
3
+ import { oAuthStateCookieName } from '../../constants.js';
4
+ import { auth } from '../../utils/contextualAuth.js';
5
+ import { saveSessionTokensToCookie } from '../../utils/saveSessionTokensToCookie.js';
6
+
7
+ const oauthCookieSchema = z.object({
8
+ codeChallenge: z.string(),
9
+ codeVerifier: z.string(),
10
+ originalUri: z.string(),
11
+ redirectUri: z.string(),
12
+ state: z.string(),
13
+ });
14
+
15
+ export async function GET(context: APIContext) {
16
+ const oauthStateCookie = context.cookies.get(oAuthStateCookieName);
17
+
18
+ if (oauthStateCookie == null) {
19
+ throw new Error(`Missing \`${oAuthStateCookieName}\` cookie`);
20
+ }
21
+
22
+ const oauthData = oauthCookieSchema.parse(JSON.parse(oauthStateCookie.value));
23
+
24
+ if (!oauthData.originalUri.startsWith('/')) {
25
+ throw new Error('Invalid `originalUri` cookie param');
26
+ }
27
+
28
+ const { code, error, errorDescription, state } = auth.parseFromUrl(
29
+ context.url.toString(),
30
+ 'query'
31
+ );
32
+
33
+ if (error != null) {
34
+ throw new Error(`Error while authenticating: \`${errorDescription}\``);
35
+ }
36
+
37
+ const memberTokens = await auth.getMemberTokens(code, state, oauthData);
38
+
39
+ context.cookies.delete(oAuthStateCookieName, {
40
+ httpOnly: true,
41
+ path: '/',
42
+ sameSite: 'lax',
43
+ secure: true,
44
+ });
45
+
46
+ saveSessionTokensToCookie(context, memberTokens);
47
+
48
+ return context.redirect(oauthData.originalUri);
49
+ }
@@ -0,0 +1,35 @@
1
+ import type { APIContext } from 'astro';
2
+ import { z } from 'zod';
3
+ import { oAuthStateCookieName } from '../../constants.js';
4
+ import { auth } from '../../utils/contextualAuth.js';
5
+
6
+ const loginSearchParams = z.object({
7
+ prompt: z.enum(['login', 'none']).optional(),
8
+ returnToUrl: z.string().optional(),
9
+ });
10
+
11
+ export async function GET({ url }: APIContext) {
12
+ const { prompt, returnToUrl } = loginSearchParams.parse(
13
+ Object.fromEntries(url.searchParams.entries())
14
+ );
15
+
16
+ const oauthData = auth.generateOAuthData(
17
+ new URL('/api/auth/callback', url).toString(),
18
+ returnToUrl
19
+ );
20
+
21
+ const { authUrl } = await auth.getAuthUrl(oauthData, {
22
+ prompt,
23
+ responseMode: 'query',
24
+ });
25
+
26
+ return new Response(null, {
27
+ headers: {
28
+ Location: authUrl,
29
+ 'Set-Cookie': `${oAuthStateCookieName}=${JSON.stringify(
30
+ oauthData
31
+ )}; Max-Age=1800; Path=/; HttpOnly; Secure; SameSite=Lax`,
32
+ },
33
+ status: 302,
34
+ });
35
+ }
@@ -0,0 +1,16 @@
1
+ import type { APIRoute } from 'astro';
2
+ import { returnToQueryParamName } from '../../constants.js';
3
+ import { auth } from '../../utils/contextualAuth.js';
4
+ import { saveSessionTokensToCookie } from '../../utils/saveSessionTokensToCookie.js';
5
+
6
+ export const GET: APIRoute = async (context) => {
7
+ const returnTo = context.url.searchParams.get(returnToQueryParamName) ?? '/';
8
+
9
+ if (!returnTo.startsWith('/')) {
10
+ throw new Error(`Invalid \`${returnToQueryParamName}\` query param`);
11
+ }
12
+
13
+ saveSessionTokensToCookie(context, await auth.generateVisitorTokens());
14
+
15
+ return context.redirect(returnTo);
16
+ };
@@ -0,0 +1,14 @@
1
+ import type { APIContext } from 'astro';
2
+ import { returnToQueryParamName } from '../../constants.js';
3
+ import { auth } from '../../utils/contextualAuth.js';
4
+
5
+ export async function POST({ redirect, request }: APIContext) {
6
+ const returnTo = request.headers.get('Referer') ?? '/';
7
+ const baseUrl = `${new URL(request.url).origin}/${import.meta.env.BASE_URL}`;
8
+ const postFlowUrl = new URL('/api/auth/logout-callback', baseUrl);
9
+ postFlowUrl.searchParams.set(returnToQueryParamName, returnTo);
10
+
11
+ const { logoutUrl } = await auth.logout(postFlowUrl.toString());
12
+
13
+ return redirect(logoutUrl);
14
+ }
@@ -0,0 +1,4 @@
1
+ import type { IOAuthStrategy } from '@wix/sdk';
2
+ import { auth as originalAuth } from '@wix/essentials';
3
+
4
+ export const auth = originalAuth.getContextualAuth<IOAuthStrategy>();
@@ -36,6 +36,22 @@ export async function writeVirtualBackofficeExtensionFiles(
36
36
  for (const component of backofficeComponents) {
37
37
  const entryFilename = resolveEntry(component);
38
38
  const originalEntrypoint = resolve(model.rootDir, entryFilename);
39
+
40
+ const virtualHocEntrypoint = join(
41
+ codegenDir,
42
+ `hoc_${component.manifest.compId}.tsx`
43
+ );
44
+
45
+ await writeFile(
46
+ virtualHocEntrypoint,
47
+ outdent`
48
+ import Component from '${toRelativePath(virtualHocEntrypoint, originalEntrypoint)}';
49
+ import { withContextualWixClient } from '@wix/dashboard/internal';
50
+
51
+ export const WrappedComponent = withContextualWixClient(Component);
52
+ `
53
+ );
54
+
39
55
  const virtualEntrypoint = join(
40
56
  codegenDir,
41
57
  `${component.manifest.compId}.astro`
@@ -45,11 +61,11 @@ export async function writeVirtualBackofficeExtensionFiles(
45
61
  virtualEntrypoint,
46
62
  outdent`
47
63
  ---
48
- import Component from '${toRelativePath(virtualEntrypoint, originalEntrypoint)}';
64
+ import { WrappedComponent } from '${toRelativePath(virtualEntrypoint, virtualHocEntrypoint)}';
49
65
  ---
50
66
 
51
67
  <div>
52
- <Component client:only="react" />
68
+ <WrappedComponent client:only="react" />
53
69
  </div>
54
70
  `
55
71
  );