@joai/sites 0.1.5 → 0.2.0
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/dist/admin.d.mts +1 -0
- package/dist/admin.mjs +47 -30
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +4 -19
- package/dist/session.d.mts +2 -3
- package/dist/session.mjs +4 -19
- package/package.json +4 -4
package/dist/admin.d.mts
CHANGED
package/dist/admin.mjs
CHANGED
|
@@ -1,49 +1,66 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { beginBrowserAppAuth, completeBrowserAppAuth } from "@joai/sdk";
|
|
3
3
|
import { useTranslations } from "next-intl";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
|
-
import { getLoginUrl } from "@joai/core";
|
|
6
5
|
import { createSessionTokenStore } from "@joai/react";
|
|
7
6
|
import { jsx } from "react/jsx-runtime";
|
|
8
7
|
//#region src/session.ts
|
|
9
|
-
function createSiteLoginUrl(config, redirect) {
|
|
10
|
-
const returnUrl = new URL(redirect);
|
|
11
|
-
returnUrl.searchParams.set("platform", "app");
|
|
12
|
-
return getLoginUrl(config.env ?? "mainnet", returnUrl.toString(), {
|
|
13
|
-
team: config.team,
|
|
14
|
-
brand: config.brand
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
8
|
function createSiteSessionStore(config) {
|
|
18
9
|
return createSessionTokenStore(config.sessionStorageKey);
|
|
19
10
|
}
|
|
20
|
-
async function exchangeSiteEditingSession(config, handoffToken) {
|
|
21
|
-
const { createClient } = await import("@joai/sdk");
|
|
22
|
-
const response = await createClient({
|
|
23
|
-
env: config.env ?? "mainnet",
|
|
24
|
-
team: config.team,
|
|
25
|
-
cache: { enabled: false }
|
|
26
|
-
}).auth.exchangeNativeSession(handoffToken);
|
|
27
|
-
if (!response.ok || !response.data?.token) throw new Error("session_exchange_failed");
|
|
28
|
-
if (!createSiteSessionStore(config).set(response.data.token)) throw new Error("session_store_failed");
|
|
29
|
-
return response.data.token;
|
|
30
|
-
}
|
|
31
11
|
//#endregion
|
|
32
12
|
//#region src/admin-login.tsx
|
|
13
|
+
const safeReturnPath = (value, fallback) => {
|
|
14
|
+
if (!value || value.includes("\\")) return fallback;
|
|
15
|
+
try {
|
|
16
|
+
const target = new URL(value, window.location.origin);
|
|
17
|
+
if (target.origin !== window.location.origin) return fallback;
|
|
18
|
+
return `${target.pathname}${target.search}${target.hash}`;
|
|
19
|
+
} catch {
|
|
20
|
+
return fallback;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
33
23
|
function SiteAdminLoginClient({ config, redirectTo = "/", className }) {
|
|
34
24
|
const t = useTranslations("sites");
|
|
35
25
|
const [message, setMessage] = useState(t("loginRedirecting"));
|
|
36
26
|
useEffect(() => {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
27
|
+
const current = new URL(window.location.href);
|
|
28
|
+
const returnTo = safeReturnPath(current.searchParams.get("return"), redirectTo);
|
|
29
|
+
const storageKey = `${config.sessionStorageKey}:auth`;
|
|
30
|
+
const begin = async () => {
|
|
31
|
+
current.searchParams.set("return", returnTo);
|
|
32
|
+
const url = await beginBrowserAppAuth({
|
|
33
|
+
callbackUrl: current.toString(),
|
|
34
|
+
env: config.env,
|
|
35
|
+
team: config.team,
|
|
36
|
+
brand: config.brand,
|
|
37
|
+
storageKey
|
|
38
|
+
});
|
|
39
|
+
window.location.replace(url);
|
|
40
|
+
};
|
|
41
|
+
const complete = async () => {
|
|
42
|
+
const token = await completeBrowserAppAuth({
|
|
43
|
+
url: window.location.href,
|
|
44
|
+
env: config.env,
|
|
45
|
+
storageKey
|
|
46
|
+
});
|
|
47
|
+
if (!token) {
|
|
48
|
+
await begin();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!createSiteSessionStore(config).set(token)) throw new Error("session_store_failed");
|
|
52
|
+
const clean = new URL(window.location.href);
|
|
53
|
+
clean.searchParams.delete("code");
|
|
54
|
+
clean.searchParams.delete("state");
|
|
55
|
+
clean.searchParams.set("return", returnTo);
|
|
56
|
+
window.history.replaceState(null, "", `${clean.pathname}${clean.search}${clean.hash}`);
|
|
57
|
+
window.location.replace(returnTo);
|
|
58
|
+
};
|
|
59
|
+
complete().catch(() => {
|
|
45
60
|
setMessage(t("loginFailed"));
|
|
46
|
-
window.setTimeout(() =>
|
|
61
|
+
window.setTimeout(() => {
|
|
62
|
+
begin().catch(() => setMessage(t("loginFailed")));
|
|
63
|
+
}, 1200);
|
|
47
64
|
});
|
|
48
65
|
}, [
|
|
49
66
|
config,
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import * as _$_joai_react0 from "@joai/react";
|
|
1
2
|
import * as _$_joai_core0 from "@joai/core";
|
|
2
3
|
import { AppEnv, Content, ContentDefinition, ContentValue, Site } from "@joai/core";
|
|
3
|
-
import * as _$_joai_react0 from "@joai/react";
|
|
4
4
|
import { ComponentType, ReactNode } from "react";
|
|
5
5
|
|
|
6
6
|
//#region src/types.d.ts
|
|
@@ -134,7 +134,6 @@ type SiteEditingSessionConfig = {
|
|
|
134
134
|
};
|
|
135
135
|
declare function createSiteLoginUrl(config: SiteEditingSessionConfig, redirect: string): string;
|
|
136
136
|
declare function createSiteSessionStore(config: SiteEditingSessionConfig): _$_joai_react0.SessionTokenStore;
|
|
137
|
-
declare function exchangeSiteEditingSession(config: SiteEditingSessionConfig, handoffToken: string): Promise<string>;
|
|
138
137
|
declare function getSiteAdminLoginPath(config: SiteEditingSessionConfig): string;
|
|
139
138
|
//#endregion
|
|
140
139
|
//#region src/theme.d.ts
|
|
@@ -253,4 +252,4 @@ declare function buildLlmsTxt(input: {
|
|
|
253
252
|
contact?: string;
|
|
254
253
|
}): string;
|
|
255
254
|
//#endregion
|
|
256
|
-
export { BuildSiteMetadataInput, LlmsTxtPage, LocalBusinessJsonLdInput, ResolveSiteOptions, ResolvedSiteContext, RevalidateHandlerOptions, SiteEditingSessionConfig, SiteHostConfig, SiteMetadataResult, SiteRobotsResult, SiteSitemapEntry, SiteTheme, SiteThemeLayoutProps, SiteThemeLocalConfig, SiteThemeMetadata, SiteThemePage, SiteThemePageProps, SiteThemePath, buildLlmsTxt, buildLocalBusinessJsonLd, buildSiteMetadata, buildSiteRobots, buildSiteSitemap, createRevalidateHandler, createSiteLoginUrl, createSiteSessionStore, createThemeRegistry, defineSiteTheme,
|
|
255
|
+
export { BuildSiteMetadataInput, LlmsTxtPage, LocalBusinessJsonLdInput, ResolveSiteOptions, ResolvedSiteContext, RevalidateHandlerOptions, SiteEditingSessionConfig, SiteHostConfig, SiteMetadataResult, SiteRobotsResult, SiteSitemapEntry, SiteTheme, SiteThemeLayoutProps, SiteThemeLocalConfig, SiteThemeMetadata, SiteThemePage, SiteThemePageProps, SiteThemePath, buildLlmsTxt, buildLocalBusinessJsonLd, buildSiteMetadata, buildSiteRobots, buildSiteSitemap, createRevalidateHandler, createSiteLoginUrl, createSiteSessionStore, createThemeRegistry, defineSiteTheme, getSiteAdminLoginPath, getSiteContentSlug, getSiteThemeKey, getThemePage, listThemeSitemapPaths, loadSiteContent, normalizeSiteHost, normalizeThemePath, resolveSiteByHost, resolveSiteContext, serializeJsonLd };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createClient } from "@joai/sdk";
|
|
2
2
|
import { revalidatePath, revalidateTag } from "next/cache";
|
|
3
|
-
import { getLoginUrl } from "@joai/core";
|
|
4
3
|
import { createSessionTokenStore } from "@joai/react";
|
|
5
4
|
//#region src/settings.ts
|
|
6
5
|
const asString = (value) => {
|
|
@@ -105,27 +104,13 @@ function createRevalidateHandler(options) {
|
|
|
105
104
|
//#endregion
|
|
106
105
|
//#region src/session.ts
|
|
107
106
|
function createSiteLoginUrl(config, redirect) {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
return
|
|
111
|
-
team: config.team,
|
|
112
|
-
brand: config.brand
|
|
113
|
-
});
|
|
107
|
+
const url = new URL(getSiteAdminLoginPath(config), "https://site.invalid");
|
|
108
|
+
url.searchParams.set("return", redirect);
|
|
109
|
+
return `${url.pathname}${url.search}`;
|
|
114
110
|
}
|
|
115
111
|
function createSiteSessionStore(config) {
|
|
116
112
|
return createSessionTokenStore(config.sessionStorageKey);
|
|
117
113
|
}
|
|
118
|
-
async function exchangeSiteEditingSession(config, handoffToken) {
|
|
119
|
-
const { createClient } = await import("@joai/sdk");
|
|
120
|
-
const response = await createClient({
|
|
121
|
-
env: config.env ?? "mainnet",
|
|
122
|
-
team: config.team,
|
|
123
|
-
cache: { enabled: false }
|
|
124
|
-
}).auth.exchangeNativeSession(handoffToken);
|
|
125
|
-
if (!response.ok || !response.data?.token) throw new Error("session_exchange_failed");
|
|
126
|
-
if (!createSiteSessionStore(config).set(response.data.token)) throw new Error("session_store_failed");
|
|
127
|
-
return response.data.token;
|
|
128
|
-
}
|
|
129
114
|
function getSiteAdminLoginPath(config) {
|
|
130
115
|
return config.loginPath ?? "/admin-login";
|
|
131
116
|
}
|
|
@@ -262,4 +247,4 @@ function buildLlmsTxt(input) {
|
|
|
262
247
|
return lines.join("\n");
|
|
263
248
|
}
|
|
264
249
|
//#endregion
|
|
265
|
-
export { buildLlmsTxt, buildLocalBusinessJsonLd, buildSiteMetadata, buildSiteRobots, buildSiteSitemap, createRevalidateHandler, createSiteLoginUrl, createSiteSessionStore, createThemeRegistry, defineSiteTheme,
|
|
250
|
+
export { buildLlmsTxt, buildLocalBusinessJsonLd, buildSiteMetadata, buildSiteRobots, buildSiteSitemap, createRevalidateHandler, createSiteLoginUrl, createSiteSessionStore, createThemeRegistry, defineSiteTheme, getSiteAdminLoginPath, getSiteContentSlug, getSiteThemeKey, getThemePage, listThemeSitemapPaths, loadSiteContent, normalizeSiteHost, normalizeThemePath, resolveSiteByHost, resolveSiteContext, serializeJsonLd };
|
package/dist/session.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AppEnv } from "@joai/core";
|
|
2
1
|
import * as _$_joai_react0 from "@joai/react";
|
|
2
|
+
import { AppEnv } from "@joai/core";
|
|
3
3
|
|
|
4
4
|
//#region src/session.d.ts
|
|
5
5
|
type SiteEditingSessionConfig = {
|
|
@@ -11,7 +11,6 @@ type SiteEditingSessionConfig = {
|
|
|
11
11
|
};
|
|
12
12
|
declare function createSiteLoginUrl(config: SiteEditingSessionConfig, redirect: string): string;
|
|
13
13
|
declare function createSiteSessionStore(config: SiteEditingSessionConfig): _$_joai_react0.SessionTokenStore;
|
|
14
|
-
declare function exchangeSiteEditingSession(config: SiteEditingSessionConfig, handoffToken: string): Promise<string>;
|
|
15
14
|
declare function getSiteAdminLoginPath(config: SiteEditingSessionConfig): string;
|
|
16
15
|
//#endregion
|
|
17
|
-
export { SiteEditingSessionConfig, createSiteLoginUrl, createSiteSessionStore,
|
|
16
|
+
export { SiteEditingSessionConfig, createSiteLoginUrl, createSiteSessionStore, getSiteAdminLoginPath };
|
package/dist/session.mjs
CHANGED
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
import { getLoginUrl } from "@joai/core";
|
|
2
1
|
import { createSessionTokenStore } from "@joai/react";
|
|
3
2
|
//#region src/session.ts
|
|
4
3
|
function createSiteLoginUrl(config, redirect) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
return
|
|
8
|
-
team: config.team,
|
|
9
|
-
brand: config.brand
|
|
10
|
-
});
|
|
4
|
+
const url = new URL(getSiteAdminLoginPath(config), "https://site.invalid");
|
|
5
|
+
url.searchParams.set("return", redirect);
|
|
6
|
+
return `${url.pathname}${url.search}`;
|
|
11
7
|
}
|
|
12
8
|
function createSiteSessionStore(config) {
|
|
13
9
|
return createSessionTokenStore(config.sessionStorageKey);
|
|
14
10
|
}
|
|
15
|
-
async function exchangeSiteEditingSession(config, handoffToken) {
|
|
16
|
-
const { createClient } = await import("@joai/sdk");
|
|
17
|
-
const response = await createClient({
|
|
18
|
-
env: config.env ?? "mainnet",
|
|
19
|
-
team: config.team,
|
|
20
|
-
cache: { enabled: false }
|
|
21
|
-
}).auth.exchangeNativeSession(handoffToken);
|
|
22
|
-
if (!response.ok || !response.data?.token) throw new Error("session_exchange_failed");
|
|
23
|
-
if (!createSiteSessionStore(config).set(response.data.token)) throw new Error("session_store_failed");
|
|
24
|
-
return response.data.token;
|
|
25
|
-
}
|
|
26
11
|
function getSiteAdminLoginPath(config) {
|
|
27
12
|
return config.loginPath ?? "/admin-login";
|
|
28
13
|
}
|
|
29
14
|
//#endregion
|
|
30
|
-
export { createSiteLoginUrl, createSiteSessionStore,
|
|
15
|
+
export { createSiteLoginUrl, createSiteSessionStore, getSiteAdminLoginPath };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joai/sites",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Shared helpers for JoAi-managed multi-tenant websites",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@joai/core": "^5.4.6",
|
|
39
|
-
"@joai/react": "^
|
|
40
|
-
"@joai/sdk": "^14.
|
|
39
|
+
"@joai/react": "^2.0.0",
|
|
40
|
+
"@joai/sdk": "^14.2.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"next": ">=15.0.0",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@types/jest": "^30.0.0",
|
|
50
50
|
"@types/react": "^19.2.14",
|
|
51
51
|
"jest": "^30.3.0",
|
|
52
|
-
"next": "^16.
|
|
52
|
+
"next": "^16.4.5",
|
|
53
53
|
"next-intl": "^4.8.3",
|
|
54
54
|
"react": "^19.2.4",
|
|
55
55
|
"react-dom": "^19.2.4",
|