@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.
- package/build/index.d.ts +3 -1
- package/build/index.js +62 -10
- package/build/index.js.map +1 -1
- package/build-browser-runtime/{chunk-HJBVRKIZ.js → setup.js} +13 -5
- package/build-runtime/chunk-C3QOE2TZ.js +7 -0
- package/build-runtime/chunk-HVACFX6T.js +18 -0
- package/build-runtime/chunk-UZPSWWI5.js +13 -0
- package/build-runtime/chunk-YMZMZCBN.js +4063 -0
- package/build-runtime/context/non-elevated.js +26 -14
- package/build-runtime/middleware/auth.js +6 -18
- package/build-runtime/routes/auth/callback.d.ts +5 -0
- package/build-runtime/routes/auth/callback.js +48 -0
- package/build-runtime/routes/auth/login.d.ts +5 -0
- package/build-runtime/routes/auth/login.js +38 -0
- package/build-runtime/routes/auth/logout-callback.d.ts +5 -0
- package/build-runtime/routes/auth/logout-callback.js +20 -0
- package/build-runtime/routes/auth/logout.d.ts +5 -0
- package/build-runtime/routes/auth/logout.js +17 -0
- package/package.json +8 -6
- package/src/constants.ts +2 -0
- package/src/context/non-elevated.ts +31 -9
- package/src/context/setup.ts +14 -0
- package/src/context/utils.ts +0 -4
- package/src/directories.ts +1 -1
- package/src/env.d.ts +2 -0
- package/src/index.ts +48 -4
- package/src/plugins/setupSsrContext.ts +9 -7
- package/src/routes/auth/callback.ts +49 -0
- package/src/routes/auth/login.ts +35 -0
- package/src/routes/auth/logout-callback.ts +16 -0
- package/src/routes/auth/logout.ts +14 -0
- package/src/utils/contextualAuth.ts +4 -0
- package/src/utils/writeVirtualBackofficeExtensionFiles.ts +18 -2
- package/tsup.config.mjs +13 -7
- package/build-browser-runtime/before-hydration.js +0 -24
- package/build-browser-runtime/page.d.ts +0 -5
- package/build-browser-runtime/page.js +0 -14
- package/src/context/before-hydration.ts +0 -21
- package/src/context/page.ts +0 -7
- /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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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,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,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,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,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.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@wix/dashboard": "^1.3.35",
|
|
6
|
-
"@wix/
|
|
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/
|
|
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/
|
|
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": "
|
|
51
|
+
"falconPackageHash": "f4b9fa1e979f7c356f0c70b13e628a4056b3205c3cbcbde60c7005de"
|
|
50
52
|
}
|
package/src/constants.ts
ADDED
|
@@ -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
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
+
}
|
package/src/context/utils.ts
CHANGED
|
@@ -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}=`));
|
package/src/directories.ts
CHANGED
package/src/env.d.ts
CHANGED
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 = (
|
|
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/
|
|
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/
|
|
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(
|
|
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
|
-
|
|
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
|
+
}
|
|
@@ -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
|
|
64
|
+
import { WrappedComponent } from '${toRelativePath(virtualEntrypoint, virtualHocEntrypoint)}';
|
|
49
65
|
---
|
|
50
66
|
|
|
51
67
|
<div>
|
|
52
|
-
<
|
|
68
|
+
<WrappedComponent client:only="react" />
|
|
53
69
|
</div>
|
|
54
70
|
`
|
|
55
71
|
);
|