@cometchat/skills-cli 2.4.1 → 3.0.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/README.md +45 -37
- package/dist/index.js +1821 -13090
- package/dist/utils/error-dictionary.js +0 -69
- package/package.json +10 -12
- package/dist/registry/schemas/config.schema.json +0 -119
- package/dist/registry/schemas/template.schema.json +0 -142
- package/dist/registry/v6/experiences/1-conversation-list/astro.template.json +0 -89
- package/dist/registry/v6/experiences/1-conversation-list/nextjs-pages.template.json +0 -83
- package/dist/registry/v6/experiences/1-conversation-list/nextjs.template.json +0 -83
- package/dist/registry/v6/experiences/1-conversation-list/react-router.template.json +0 -102
- package/dist/registry/v6/experiences/1-conversation-list/reactjs-dedicated-route.template.json +0 -81
- package/dist/registry/v6/experiences/1-conversation-list/reactjs.template.json +0 -86
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/ChatApp.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/ChatApp.tsx.tpl +0 -86
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/chat.astro.tpl +0 -17
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatNoSSR.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatNoSSR.tsx.tpl +0 -86
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatSelector.tsx.tpl +0 -41
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/chat-page.tsx.tpl +0 -11
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatNoSSR.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatNoSSR.tsx.tpl +0 -88
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatSelector.tsx.tpl +0 -41
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/chat-page.tsx.tpl +0 -15
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChat-route.tsx.tpl +0 -22
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatNoSSR.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatNoSSR.tsx.tpl +0 -87
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/App.css.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/App.tsx.tpl +0 -55
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/main.tsx.tpl +0 -46
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/ChatPage.tsx.tpl +0 -87
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/CometChatMessenger.css.tpl +0 -20
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/CometChatMessenger.tsx.tpl +0 -54
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/2-one-to-one/astro.template.json +0 -81
- package/dist/registry/v6/experiences/2-one-to-one/nextjs.template.json +0 -77
- package/dist/registry/v6/experiences/2-one-to-one/react-router.template.json +0 -93
- package/dist/registry/v6/experiences/2-one-to-one/reactjs-dedicated-route.template.json +0 -75
- package/dist/registry/v6/experiences/2-one-to-one/reactjs.template.json +0 -80
- package/dist/registry/v6/experiences/2-one-to-one/templates/astro/ChatApp.css.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/astro/ChatApp.tsx.tpl +0 -66
- package/dist/registry/v6/experiences/2-one-to-one/templates/astro/chat.astro.tpl +0 -17
- package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/CometChatNoSSR.css.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/CometChatNoSSR.tsx.tpl +0 -66
- package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/chat-page.tsx.tpl +0 -11
- package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChat-route.tsx.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChatNoSSR.css.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChatNoSSR.tsx.tpl +0 -67
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/App.css.tpl +0 -4
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/App.tsx.tpl +0 -44
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/main.tsx.tpl +0 -46
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs-dedicated-route/ChatPage.tsx.tpl +0 -84
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs-dedicated-route/CometChatMessenger.css.tpl +0 -9
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs-dedicated-route/CometChatMessenger.tsx.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/astro.template.json +0 -93
- package/dist/registry/v6/experiences/3-tab-based/nextjs.template.json +0 -90
- package/dist/registry/v6/experiences/3-tab-based/react-router.template.json +0 -105
- package/dist/registry/v6/experiences/3-tab-based/reactjs-dedicated-route.template.json +0 -89
- package/dist/registry/v6/experiences/3-tab-based/reactjs.template.json +0 -93
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/ChatApp.css.tpl +0 -39
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/ChatApp.tsx.tpl +0 -93
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/chat.astro.tpl +0 -17
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatNoSSR.css.tpl +0 -39
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatNoSSR.tsx.tpl +0 -93
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatTabs.tsx.tpl +0 -73
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/chat-page.tsx.tpl +0 -11
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChat-route.tsx.tpl +0 -21
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatNoSSR.css.tpl +0 -39
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatNoSSR.tsx.tpl +0 -94
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/App.css.tpl +0 -7
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/App.tsx.tpl +0 -62
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/main.tsx.tpl +0 -46
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/ChatPage.tsx.tpl +0 -84
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatMessenger.css.tpl +0 -11
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatMessenger.tsx.tpl +0 -61
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/features/catalog.json +0 -990
- package/dist/registry/v6/production/astro/cometchat-token.ts.tpl +0 -86
- package/dist/registry/v6/production/astro.template.json +0 -51
- package/dist/registry/v6/production/nextjs/route.ts.tpl +0 -79
- package/dist/registry/v6/production/nextjs.template.json +0 -50
- package/dist/registry/v6/production/react-router/api.cometchat-token.ts.tpl +0 -73
- package/dist/registry/v6/production/react-router.template.json +0 -58
- package/dist/registry/v6/user-mgmt/astro/cometchat-user.ts.tpl +0 -164
- package/dist/registry/v6/user-mgmt/astro.template.json +0 -33
- package/dist/registry/v6/user-mgmt/nextjs/route.ts.tpl +0 -212
- package/dist/registry/v6/user-mgmt/nextjs.template.json +0 -57
- package/dist/registry/v6/user-mgmt/react-router/api.cometchat-user.ts.tpl +0 -176
- package/dist/registry/v6/user-mgmt/react-router.template.json +0 -40
- package/dist/registry/v6/widget/astro/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/astro/CometChatWidget.tsx.tpl +0 -88
- package/dist/registry/v6/widget/astro.template.json +0 -38
- package/dist/registry/v6/widget/nextjs/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/nextjs/CometChatWidget.tsx.tpl +0 -88
- package/dist/registry/v6/widget/nextjs.template.json +0 -40
- package/dist/registry/v6/widget/react-router/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/react-router/CometChatWidget.tsx.tpl +0 -98
- package/dist/registry/v6/widget/react-router.template.json +0 -36
- package/dist/registry/v6/widget/reactjs/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/reactjs/CometChatWidget.tsx.tpl +0 -89
- package/dist/registry/v6/widget/reactjs.template.json +0 -36
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /api/cometchat-token — server-side endpoint that mints CometChat auth tokens.
|
|
3
|
-
*
|
|
4
|
-
* Astro API route. The Auth Key NEVER leaves the server. The client calls
|
|
5
|
-
* this endpoint to get a short-lived auth token, then passes it to
|
|
6
|
-
* CometChatUIKit.loginWithAuthToken().
|
|
7
|
-
*
|
|
8
|
-
* Generated by `cometchat production-auth`. Customize freely:
|
|
9
|
-
* - Add real authentication: read the user's session cookie / JWT here
|
|
10
|
-
* - Map your app's user IDs to CometChat UIDs
|
|
11
|
-
* - Add rate limiting if exposed publicly
|
|
12
|
-
*
|
|
13
|
-
* Astro requirement: your astro.config.mjs must have `output: 'server'` or
|
|
14
|
-
* `output: 'hybrid'` for API routes to work. Static-only Astro builds
|
|
15
|
-
* cannot run server-side endpoints.
|
|
16
|
-
*
|
|
17
|
-
* Security note: this file MUST NOT use PUBLIC_* env vars for the Auth Key.
|
|
18
|
-
* The whole point is to keep the Auth Key out of the browser.
|
|
19
|
-
*/
|
|
20
|
-
import type { APIRoute } from "astro";
|
|
21
|
-
|
|
22
|
-
const COMETCHAT_APP_ID = import.meta.env.PUBLIC_COMETCHAT_APP_ID!;
|
|
23
|
-
const COMETCHAT_REGION = import.meta.env.PUBLIC_COMETCHAT_REGION!;
|
|
24
|
-
// IMPORTANT: server-only — no PUBLIC_ prefix
|
|
25
|
-
const COMETCHAT_AUTH_KEY = import.meta.env.COMETCHAT_AUTH_KEY!;
|
|
26
|
-
|
|
27
|
-
export const GET: APIRoute = async ({ request }) => {
|
|
28
|
-
const url = new URL(request.url);
|
|
29
|
-
// ⚠ Replace this with your real auth: read the session, extract the user ID,
|
|
30
|
-
// then map it to a CometChat UID. Do not trust the query param in production.
|
|
31
|
-
const uid = url.searchParams.get("uid") ?? "cometchat-uid-1";
|
|
32
|
-
|
|
33
|
-
if (!COMETCHAT_APP_ID || !COMETCHAT_REGION || !COMETCHAT_AUTH_KEY) {
|
|
34
|
-
return new Response(
|
|
35
|
-
JSON.stringify({ error: "CometChat credentials not configured on the server" }),
|
|
36
|
-
{ status: 500, headers: { "Content-Type": "application/json" } },
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const res = await fetch(
|
|
42
|
-
`https://${COMETCHAT_APP_ID}.api-${COMETCHAT_REGION}.cometchat.io/v3/users/${encodeURIComponent(uid)}/auth_tokens`,
|
|
43
|
-
{
|
|
44
|
-
method: "POST",
|
|
45
|
-
headers: {
|
|
46
|
-
"Content-Type": "application/json",
|
|
47
|
-
appid: COMETCHAT_APP_ID,
|
|
48
|
-
apikey: COMETCHAT_AUTH_KEY,
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
if (!res.ok) {
|
|
54
|
-
const text = await res.text();
|
|
55
|
-
return new Response(
|
|
56
|
-
JSON.stringify({ error: `CometChat token mint failed (${res.status})`, detail: text }),
|
|
57
|
-
{ status: 502, headers: { "Content-Type": "application/json" } },
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const body = (await res.json()) as { data?: { authToken?: string } };
|
|
62
|
-
const authToken = body.data?.authToken;
|
|
63
|
-
if (!authToken) {
|
|
64
|
-
return new Response(
|
|
65
|
-
JSON.stringify({ error: "CometChat returned no authToken in response" }),
|
|
66
|
-
{ status: 502, headers: { "Content-Type": "application/json" } },
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return new Response(JSON.stringify({ authToken, uid }), {
|
|
71
|
-
status: 200,
|
|
72
|
-
headers: { "Content-Type": "application/json" },
|
|
73
|
-
});
|
|
74
|
-
} catch (err) {
|
|
75
|
-
return new Response(
|
|
76
|
-
JSON.stringify({
|
|
77
|
-
error: "Token mint failed",
|
|
78
|
-
detail: err instanceof Error ? err.message : String(err),
|
|
79
|
-
}),
|
|
80
|
-
{ status: 500, headers: { "Content-Type": "application/json" } },
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// Astro requires this for non-static routes
|
|
86
|
-
export const prerender = false;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "../../schemas/template.schema.json",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"experience_id": 1,
|
|
5
|
-
"framework": "astro",
|
|
6
|
-
"sdk_compatibility": ">=6.0.0 <7.0.0",
|
|
7
|
-
"default_placement": "dedicated-route",
|
|
8
|
-
"deps": [],
|
|
9
|
-
"env_vars": [
|
|
10
|
-
{
|
|
11
|
-
"name": "COMETCHAT_AUTH_KEY",
|
|
12
|
-
"required": true,
|
|
13
|
-
"secret": true,
|
|
14
|
-
"description": "Server-side only Auth Key (no PUBLIC_ prefix). Used by the /api/cometchat-token endpoint to mint user-scoped auth tokens. Remove PUBLIC_COMETCHAT_AUTH_KEY from .env — that variable is for development only and exposes the key to the browser."
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"name": "PUBLIC_COMETCHAT_APP_ID",
|
|
18
|
-
"required": true,
|
|
19
|
-
"description": "Same as before — App ID is safe to expose"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"name": "PUBLIC_COMETCHAT_REGION",
|
|
23
|
-
"required": true,
|
|
24
|
-
"description": "Same as before — region is safe to expose"
|
|
25
|
-
}
|
|
26
|
-
],
|
|
27
|
-
"files": [
|
|
28
|
-
{
|
|
29
|
-
"path": "src/pages/api/cometchat-token.ts",
|
|
30
|
-
"action": "create",
|
|
31
|
-
"template_ref": "cometchat-token.ts.tpl",
|
|
32
|
-
"owned": true
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"verify_rules": [],
|
|
36
|
-
"next_steps": [
|
|
37
|
-
"1. Make sure your astro.config.mjs has output: 'server' or 'hybrid' (API endpoints need SSR-capable output).",
|
|
38
|
-
"2. Add COMETCHAT_AUTH_KEY (NO PUBLIC_ prefix) to .env with your CometChat Auth Key.",
|
|
39
|
-
"3. REMOVE PUBLIC_COMETCHAT_AUTH_KEY from .env (keep APP_ID and REGION).",
|
|
40
|
-
"4. In src/cometchat/ChatApp.tsx, replace the login flow:",
|
|
41
|
-
" FROM: CometChatUIKit.login('cometchat-uid-1').then(setUser).catch(setError);",
|
|
42
|
-
" TO: fetch('/api/cometchat-token?uid=' + encodeURIComponent(userId))",
|
|
43
|
-
" .then(r => r.json())",
|
|
44
|
-
" .then(data => CometChatUIKit.loginWithAuthToken(data.authToken))",
|
|
45
|
-
" .then(setUser)",
|
|
46
|
-
" .catch(e => setError(String(e)));",
|
|
47
|
-
"5. Replace 'cometchat-uid-1' with your real authenticated user's ID.",
|
|
48
|
-
"6. Restart the dev server (`npm run dev`) so the new env var takes effect.",
|
|
49
|
-
"7. The Auth Key is now ONLY in server memory — never sent to the browser."
|
|
50
|
-
]
|
|
51
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /api/cometchat-token — server-side endpoint that mints CometChat auth tokens.
|
|
3
|
-
*
|
|
4
|
-
* This is the production-mode replacement for client-side login(UID) + Auth Key.
|
|
5
|
-
* The Auth Key NEVER leaves the server. The client calls this endpoint to get
|
|
6
|
-
* a short-lived auth token, then passes it to CometChatUIKit.loginWithAuthToken().
|
|
7
|
-
*
|
|
8
|
-
* Generated by `cometchat production-auth`. Customize freely:
|
|
9
|
-
* - Add real authentication: read the user's session cookie / JWT here, do
|
|
10
|
-
* not trust the `?uid=` query param in production.
|
|
11
|
-
* - Map your app's user IDs to CometChat UIDs.
|
|
12
|
-
* - Add rate limiting if exposed publicly.
|
|
13
|
-
* - Cache tokens per UID for short windows to reduce CometChat API load.
|
|
14
|
-
*
|
|
15
|
-
* Security note: this file MUST NOT use NEXT_PUBLIC_* env vars for the Auth Key.
|
|
16
|
-
* The whole point of this endpoint is to keep the Auth Key out of the browser.
|
|
17
|
-
*/
|
|
18
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
19
|
-
|
|
20
|
-
const COMETCHAT_APP_ID = process.env.NEXT_PUBLIC_COMETCHAT_APP_ID!;
|
|
21
|
-
const COMETCHAT_REGION = process.env.NEXT_PUBLIC_COMETCHAT_REGION!;
|
|
22
|
-
// IMPORTANT: server-only — no NEXT_PUBLIC_ prefix
|
|
23
|
-
const COMETCHAT_AUTH_KEY = process.env.COMETCHAT_AUTH_KEY!;
|
|
24
|
-
|
|
25
|
-
export async function GET(request: NextRequest) {
|
|
26
|
-
// ⚠ Replace this with your real auth: read the session, extract the user ID,
|
|
27
|
-
// then map it to a CometChat UID. Do not trust the query param in production.
|
|
28
|
-
const uid = request.nextUrl.searchParams.get("uid") ?? "cometchat-uid-1";
|
|
29
|
-
|
|
30
|
-
if (!COMETCHAT_APP_ID || !COMETCHAT_REGION || !COMETCHAT_AUTH_KEY) {
|
|
31
|
-
return NextResponse.json(
|
|
32
|
-
{ error: "CometChat credentials not configured on the server" },
|
|
33
|
-
{ status: 500 },
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
// Mint a fresh auth token for this UID via the CometChat REST API.
|
|
39
|
-
// Endpoint: POST https://{appId}.api-{region}.cometchat.io/v3/users/{uid}/auth_tokens
|
|
40
|
-
const res = await fetch(
|
|
41
|
-
`https://${COMETCHAT_APP_ID}.api-${COMETCHAT_REGION}.cometchat.io/v3/users/${encodeURIComponent(uid)}/auth_tokens`,
|
|
42
|
-
{
|
|
43
|
-
method: "POST",
|
|
44
|
-
headers: {
|
|
45
|
-
"Content-Type": "application/json",
|
|
46
|
-
appid: COMETCHAT_APP_ID,
|
|
47
|
-
apikey: COMETCHAT_AUTH_KEY,
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
if (!res.ok) {
|
|
53
|
-
const text = await res.text();
|
|
54
|
-
return NextResponse.json(
|
|
55
|
-
{ error: `CometChat token mint failed (${res.status})`, detail: text },
|
|
56
|
-
{ status: 502 },
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const body = (await res.json()) as { data?: { authToken?: string } };
|
|
61
|
-
const authToken = body.data?.authToken;
|
|
62
|
-
if (!authToken) {
|
|
63
|
-
return NextResponse.json(
|
|
64
|
-
{ error: "CometChat returned no authToken in response" },
|
|
65
|
-
{ status: 502 },
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return NextResponse.json({ authToken, uid });
|
|
70
|
-
} catch (err) {
|
|
71
|
-
return NextResponse.json(
|
|
72
|
-
{ error: "Token mint failed", detail: err instanceof Error ? err.message : String(err) },
|
|
73
|
-
{ status: 500 },
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Disable static rendering — this is a dynamic API route
|
|
79
|
-
export const dynamic = "force-dynamic";
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "../../schemas/template.schema.json",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"experience_id": 1,
|
|
5
|
-
"framework": "nextjs",
|
|
6
|
-
"sdk_compatibility": ">=6.0.0 <7.0.0",
|
|
7
|
-
"default_placement": "dedicated-route",
|
|
8
|
-
"deps": [],
|
|
9
|
-
"env_vars": [
|
|
10
|
-
{
|
|
11
|
-
"name": "COMETCHAT_AUTH_KEY",
|
|
12
|
-
"required": true,
|
|
13
|
-
"secret": true,
|
|
14
|
-
"description": "Server-side only Auth Key (no NEXT_PUBLIC_ prefix). Used by the /api/cometchat-token endpoint to mint user-scoped auth tokens. Remove NEXT_PUBLIC_COMETCHAT_AUTH_KEY from .env.local — that variable is for development only and exposes the key to the browser."
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"name": "NEXT_PUBLIC_COMETCHAT_APP_ID",
|
|
18
|
-
"required": true,
|
|
19
|
-
"description": "Same as before — App ID is safe to expose"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"name": "NEXT_PUBLIC_COMETCHAT_REGION",
|
|
23
|
-
"required": true,
|
|
24
|
-
"description": "Same as before — region is safe to expose"
|
|
25
|
-
}
|
|
26
|
-
],
|
|
27
|
-
"files": [
|
|
28
|
-
{
|
|
29
|
-
"path": "src/app/api/cometchat-token/route.ts",
|
|
30
|
-
"action": "create",
|
|
31
|
-
"template_ref": "route.ts.tpl",
|
|
32
|
-
"owned": true
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"verify_rules": [],
|
|
36
|
-
"next_steps": [
|
|
37
|
-
"1. Add COMETCHAT_AUTH_KEY (NO NEXT_PUBLIC_ prefix) to .env.local with your CometChat Auth Key.",
|
|
38
|
-
"2. REMOVE NEXT_PUBLIC_COMETCHAT_AUTH_KEY from .env.local (keep APP_ID and REGION).",
|
|
39
|
-
"3. In src/app/cometchat/CometChatNoSSR.tsx, replace the login flow:",
|
|
40
|
-
" FROM: CometChatUIKit.login('cometchat-uid-1').then(setUser).catch(setError);",
|
|
41
|
-
" TO: fetch('/api/cometchat-token?uid=' + encodeURIComponent(userId))",
|
|
42
|
-
" .then(r => r.json())",
|
|
43
|
-
" .then(data => CometChatUIKit.loginWithAuthToken(data.authToken))",
|
|
44
|
-
" .then(setUser)",
|
|
45
|
-
" .catch(e => setError(String(e)));",
|
|
46
|
-
"4. Replace the hardcoded 'cometchat-uid-1' with your real authenticated user's ID.",
|
|
47
|
-
"5. Restart the dev server (`npm run dev`) so the new env var takes effect.",
|
|
48
|
-
"6. The Auth Key is now ONLY in server memory — never sent to the browser."
|
|
49
|
-
]
|
|
50
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /api/cometchat-token — server-side endpoint that mints CometChat auth tokens.
|
|
3
|
-
*
|
|
4
|
-
* React Router v7 framework mode loader. The Auth Key NEVER leaves the
|
|
5
|
-
* server. The client calls this endpoint to get a short-lived auth token,
|
|
6
|
-
* then passes it to CometChatUIKit.loginWithAuthToken().
|
|
7
|
-
*
|
|
8
|
-
* Generated by `cometchat production-auth`. Customize freely:
|
|
9
|
-
* - Add real authentication: read the user's session cookie / JWT here
|
|
10
|
-
* - Map your app's user IDs to CometChat UIDs
|
|
11
|
-
* - Add rate limiting if exposed publicly
|
|
12
|
-
*
|
|
13
|
-
* Security note: this file MUST NOT use VITE_* env vars for the Auth Key.
|
|
14
|
-
* The whole point is to keep the Auth Key out of the browser.
|
|
15
|
-
*/
|
|
16
|
-
import type { LoaderFunctionArgs } from "react-router";
|
|
17
|
-
|
|
18
|
-
const COMETCHAT_APP_ID = process.env.VITE_COMETCHAT_APP_ID!;
|
|
19
|
-
const COMETCHAT_REGION = process.env.VITE_COMETCHAT_REGION!;
|
|
20
|
-
// IMPORTANT: server-only — no VITE_ prefix
|
|
21
|
-
const COMETCHAT_AUTH_KEY = process.env.COMETCHAT_AUTH_KEY!;
|
|
22
|
-
|
|
23
|
-
export async function loader({ request }: LoaderFunctionArgs) {
|
|
24
|
-
const url = new URL(request.url);
|
|
25
|
-
// ⚠ Replace this with your real auth: read the session, extract the user ID,
|
|
26
|
-
// then map it to a CometChat UID. Do not trust the query param in production.
|
|
27
|
-
const uid = url.searchParams.get("uid") ?? "cometchat-uid-1";
|
|
28
|
-
|
|
29
|
-
if (!COMETCHAT_APP_ID || !COMETCHAT_REGION || !COMETCHAT_AUTH_KEY) {
|
|
30
|
-
return Response.json(
|
|
31
|
-
{ error: "CometChat credentials not configured on the server" },
|
|
32
|
-
{ status: 500 },
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
const res = await fetch(
|
|
38
|
-
`https://${COMETCHAT_APP_ID}.api-${COMETCHAT_REGION}.cometchat.io/v3/users/${encodeURIComponent(uid)}/auth_tokens`,
|
|
39
|
-
{
|
|
40
|
-
method: "POST",
|
|
41
|
-
headers: {
|
|
42
|
-
"Content-Type": "application/json",
|
|
43
|
-
appid: COMETCHAT_APP_ID,
|
|
44
|
-
apikey: COMETCHAT_AUTH_KEY,
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
if (!res.ok) {
|
|
50
|
-
const text = await res.text();
|
|
51
|
-
return Response.json(
|
|
52
|
-
{ error: `CometChat token mint failed (${res.status})`, detail: text },
|
|
53
|
-
{ status: 502 },
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const body = (await res.json()) as { data?: { authToken?: string } };
|
|
58
|
-
const authToken = body.data?.authToken;
|
|
59
|
-
if (!authToken) {
|
|
60
|
-
return Response.json(
|
|
61
|
-
{ error: "CometChat returned no authToken in response" },
|
|
62
|
-
{ status: 502 },
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return Response.json({ authToken, uid });
|
|
67
|
-
} catch (err) {
|
|
68
|
-
return Response.json(
|
|
69
|
-
{ error: "Token mint failed", detail: err instanceof Error ? err.message : String(err) },
|
|
70
|
-
{ status: 500 },
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "../../schemas/template.schema.json",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"experience_id": 1,
|
|
5
|
-
"framework": "react-router",
|
|
6
|
-
"sdk_compatibility": ">=6.0.0 <7.0.0",
|
|
7
|
-
"default_placement": "dedicated-route",
|
|
8
|
-
"deps": [],
|
|
9
|
-
"env_vars": [
|
|
10
|
-
{
|
|
11
|
-
"name": "COMETCHAT_AUTH_KEY",
|
|
12
|
-
"required": true,
|
|
13
|
-
"secret": true,
|
|
14
|
-
"description": "Server-side only Auth Key (no VITE_ prefix). Used by the /api/cometchat-token loader to mint user-scoped auth tokens. Remove VITE_COMETCHAT_AUTH_KEY from .env — that variable is for development only and exposes the key to the browser."
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"name": "VITE_COMETCHAT_APP_ID",
|
|
18
|
-
"required": true,
|
|
19
|
-
"description": "Same as before — App ID is safe to expose"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"name": "VITE_COMETCHAT_REGION",
|
|
23
|
-
"required": true,
|
|
24
|
-
"description": "Same as before — region is safe to expose"
|
|
25
|
-
}
|
|
26
|
-
],
|
|
27
|
-
"files": [
|
|
28
|
-
{
|
|
29
|
-
"path": "app/routes/api.cometchat-token.ts",
|
|
30
|
-
"action": "create",
|
|
31
|
-
"template_ref": "api.cometchat-token.ts.tpl",
|
|
32
|
-
"owned": true
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"path": "app/routes.ts",
|
|
36
|
-
"action": "patch",
|
|
37
|
-
"patch_mode": "insert-before",
|
|
38
|
-
"anchor": "] satisfies RouteConfig",
|
|
39
|
-
"patch_content": " route(\"api/cometchat-token\", \"routes/api.cometchat-token.ts\"),\n",
|
|
40
|
-
"skip_if_exists": "routes/api.cometchat-token.ts"
|
|
41
|
-
}
|
|
42
|
-
],
|
|
43
|
-
"verify_rules": [],
|
|
44
|
-
"next_steps": [
|
|
45
|
-
"1. Add COMETCHAT_AUTH_KEY (NO VITE_ prefix) to .env with your CometChat Auth Key.",
|
|
46
|
-
"2. REMOVE VITE_COMETCHAT_AUTH_KEY from .env (keep APP_ID and REGION).",
|
|
47
|
-
"3. In app/cometchat/CometChatNoSSR.tsx, replace the login flow:",
|
|
48
|
-
" FROM: CometChatUIKit.login('cometchat-uid-1').then(setUser).catch(setError);",
|
|
49
|
-
" TO: fetch('/api/cometchat-token?uid=' + encodeURIComponent(userId))",
|
|
50
|
-
" .then(r => r.json())",
|
|
51
|
-
" .then(data => CometChatUIKit.loginWithAuthToken(data.authToken))",
|
|
52
|
-
" .then(setUser)",
|
|
53
|
-
" .catch(e => setError(String(e)));",
|
|
54
|
-
"4. Replace 'cometchat-uid-1' with your real authenticated user's ID.",
|
|
55
|
-
"5. Restart the dev server (`npm run dev`) so the new env var takes effect.",
|
|
56
|
-
"6. The Auth Key is now ONLY in server memory — never sent to the browser."
|
|
57
|
-
]
|
|
58
|
-
}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /api/cometchat-user — server-side CometChat user management.
|
|
3
|
-
*
|
|
4
|
-
* Astro API route. Handles POST (create), PUT (update), DELETE.
|
|
5
|
-
* The Auth Key NEVER leaves the server.
|
|
6
|
-
*
|
|
7
|
-
* Requires astro.config.mjs to have `output: 'server'` or `'hybrid'`.
|
|
8
|
-
*
|
|
9
|
-
* Generated by `cometchat add-user-mgmt`.
|
|
10
|
-
*
|
|
11
|
-
* SECURITY: this template is unauthenticated by design — add your own
|
|
12
|
-
* session check before exposing it publicly.
|
|
13
|
-
*/
|
|
14
|
-
import type { APIRoute } from "astro";
|
|
15
|
-
|
|
16
|
-
const COMETCHAT_APP_ID = import.meta.env.PUBLIC_COMETCHAT_APP_ID!;
|
|
17
|
-
const COMETCHAT_REGION = import.meta.env.PUBLIC_COMETCHAT_REGION!;
|
|
18
|
-
const COMETCHAT_AUTH_KEY = import.meta.env.COMETCHAT_AUTH_KEY!;
|
|
19
|
-
|
|
20
|
-
const COMETCHAT_API_BASE = `https://${COMETCHAT_APP_ID}.api-${COMETCHAT_REGION}.cometchat.io/v3`;
|
|
21
|
-
|
|
22
|
-
const baseHeaders = {
|
|
23
|
-
"Content-Type": "application/json",
|
|
24
|
-
appid: COMETCHAT_APP_ID,
|
|
25
|
-
apikey: COMETCHAT_AUTH_KEY,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
function json(data: unknown, status = 200) {
|
|
29
|
-
return new Response(JSON.stringify(data), {
|
|
30
|
-
status,
|
|
31
|
-
headers: { "Content-Type": "application/json" },
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function validateUid(uid: unknown): string | null {
|
|
36
|
-
if (typeof uid !== "string" || uid.length === 0) return "uid is required";
|
|
37
|
-
if (uid.length > 100) return "uid must be ≤100 characters";
|
|
38
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(uid)) {
|
|
39
|
-
return "uid must contain only alphanumeric characters, hyphens, and underscores";
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function configError() {
|
|
45
|
-
if (!COMETCHAT_APP_ID || !COMETCHAT_REGION || !COMETCHAT_AUTH_KEY) {
|
|
46
|
-
return json({ error: "CometChat credentials not configured on the server" }, 500);
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export const POST: APIRoute = async ({ request }) => {
|
|
52
|
-
const cfgErr = configError();
|
|
53
|
-
if (cfgErr) return cfgErr;
|
|
54
|
-
|
|
55
|
-
let body;
|
|
56
|
-
try {
|
|
57
|
-
body = await request.json();
|
|
58
|
-
} catch {
|
|
59
|
-
return json({ error: "Invalid JSON body" }, 400);
|
|
60
|
-
}
|
|
61
|
-
const uidError = validateUid(body.uid);
|
|
62
|
-
if (uidError) return json({ error: uidError }, 400);
|
|
63
|
-
if (!body.name) return json({ error: "name is required" }, 400);
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
const res = await fetch(`${COMETCHAT_API_BASE}/users`, {
|
|
67
|
-
method: "POST",
|
|
68
|
-
headers: baseHeaders,
|
|
69
|
-
body: JSON.stringify({
|
|
70
|
-
uid: body.uid,
|
|
71
|
-
name: body.name,
|
|
72
|
-
...(body.avatar && { avatar: body.avatar }),
|
|
73
|
-
...(body.metadata && { metadata: body.metadata }),
|
|
74
|
-
...(body.tags && { tags: body.tags }),
|
|
75
|
-
}),
|
|
76
|
-
});
|
|
77
|
-
if (!res.ok) {
|
|
78
|
-
const detail = await res.text();
|
|
79
|
-
return json(
|
|
80
|
-
{ error: `CometChat user create failed (${res.status})`, detail },
|
|
81
|
-
res.status === 409 ? 409 : 502,
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
const data = await res.json();
|
|
85
|
-
return json({ user: data.data }, 201);
|
|
86
|
-
} catch (err) {
|
|
87
|
-
return json(
|
|
88
|
-
{ error: "Create failed", detail: err instanceof Error ? err.message : String(err) },
|
|
89
|
-
500,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export const PUT: APIRoute = async ({ request }) => {
|
|
95
|
-
const cfgErr = configError();
|
|
96
|
-
if (cfgErr) return cfgErr;
|
|
97
|
-
|
|
98
|
-
let body;
|
|
99
|
-
try {
|
|
100
|
-
body = await request.json();
|
|
101
|
-
} catch {
|
|
102
|
-
return json({ error: "Invalid JSON body" }, 400);
|
|
103
|
-
}
|
|
104
|
-
const uidError = validateUid(body.uid);
|
|
105
|
-
if (uidError) return json({ error: uidError }, 400);
|
|
106
|
-
|
|
107
|
-
const updates: Record<string, unknown> = {};
|
|
108
|
-
if (body.name !== undefined) updates.name = body.name;
|
|
109
|
-
if (body.avatar !== undefined) updates.avatar = body.avatar;
|
|
110
|
-
if (body.metadata !== undefined) updates.metadata = body.metadata;
|
|
111
|
-
if (body.tags !== undefined) updates.tags = body.tags;
|
|
112
|
-
if (Object.keys(updates).length === 0) {
|
|
113
|
-
return json({ error: "No fields to update" }, 400);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const res = await fetch(`${COMETCHAT_API_BASE}/users/${encodeURIComponent(body.uid)}`, {
|
|
118
|
-
method: "PUT",
|
|
119
|
-
headers: baseHeaders,
|
|
120
|
-
body: JSON.stringify(updates),
|
|
121
|
-
});
|
|
122
|
-
if (!res.ok) {
|
|
123
|
-
const detail = await res.text();
|
|
124
|
-
return json({ error: `CometChat user update failed (${res.status})`, detail }, 502);
|
|
125
|
-
}
|
|
126
|
-
const data = await res.json();
|
|
127
|
-
return json({ user: data.data });
|
|
128
|
-
} catch (err) {
|
|
129
|
-
return json(
|
|
130
|
-
{ error: "Update failed", detail: err instanceof Error ? err.message : String(err) },
|
|
131
|
-
500,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export const DELETE: APIRoute = async ({ request }) => {
|
|
137
|
-
const cfgErr = configError();
|
|
138
|
-
if (cfgErr) return cfgErr;
|
|
139
|
-
|
|
140
|
-
const url = new URL(request.url);
|
|
141
|
-
const uid = url.searchParams.get("uid");
|
|
142
|
-
const uidError = validateUid(uid);
|
|
143
|
-
if (uidError) return json({ error: uidError }, 400);
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
const res = await fetch(`${COMETCHAT_API_BASE}/users/${encodeURIComponent(uid as string)}`, {
|
|
147
|
-
method: "DELETE",
|
|
148
|
-
headers: baseHeaders,
|
|
149
|
-
body: JSON.stringify({ permanent: true }),
|
|
150
|
-
});
|
|
151
|
-
if (!res.ok) {
|
|
152
|
-
const detail = await res.text();
|
|
153
|
-
return json({ error: `CometChat user delete failed (${res.status})`, detail }, 502);
|
|
154
|
-
}
|
|
155
|
-
return json({ deleted: uid });
|
|
156
|
-
} catch (err) {
|
|
157
|
-
return json(
|
|
158
|
-
{ error: "Delete failed", detail: err instanceof Error ? err.message : String(err) },
|
|
159
|
-
500,
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
export const prerender = false;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "../../schemas/template.schema.json",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"experience_id": 1,
|
|
5
|
-
"framework": "astro",
|
|
6
|
-
"sdk_compatibility": ">=6.0.0 <7.0.0",
|
|
7
|
-
"default_placement": "dedicated-route",
|
|
8
|
-
"deps": [],
|
|
9
|
-
"env_vars": [
|
|
10
|
-
{
|
|
11
|
-
"name": "COMETCHAT_AUTH_KEY",
|
|
12
|
-
"required": true,
|
|
13
|
-
"secret": true,
|
|
14
|
-
"description": "Server-side only Auth Key (no PUBLIC_ prefix)."
|
|
15
|
-
}
|
|
16
|
-
],
|
|
17
|
-
"files": [
|
|
18
|
-
{
|
|
19
|
-
"path": "src/pages/api/cometchat-user.ts",
|
|
20
|
-
"action": "create",
|
|
21
|
-
"template_ref": "cometchat-user.ts.tpl",
|
|
22
|
-
"owned": true
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"verify_rules": [],
|
|
26
|
-
"next_steps": [
|
|
27
|
-
"1. Make sure your astro.config.mjs has output: 'server' or 'hybrid'.",
|
|
28
|
-
"2. Endpoint at /api/cometchat-user supports POST (create), PUT (update), DELETE.",
|
|
29
|
-
"3. Add COMETCHAT_AUTH_KEY (no PUBLIC_ prefix) to .env.",
|
|
30
|
-
"4. Wire it into your sign-up flow when an app user is created.",
|
|
31
|
-
"5. SECURITY: this template is unauthenticated. Add session checks before deploying."
|
|
32
|
-
]
|
|
33
|
-
}
|