minutework 0.1.31 → 0.1.33
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/EXTERNAL_ALPHA.md +33 -33
- package/README.md +34 -34
- package/assets/claude-local/CLAUDE.md.template +12 -12
- package/assets/claude-local/skills/README.md +3 -1
- package/assets/claude-local/skills/app-pack-authoring/SKILL.md +17 -4
- package/assets/claude-local/skills/capability-gap-reporting/SKILL.md +3 -3
- package/assets/claude-local/skills/contract-first-public-intake/SKILL.md +11 -3
- package/assets/claude-local/skills/generated-workspace-architecture/SKILL.md +12 -5
- package/assets/claude-local/skills/layering-and-import-modes/SKILL.md +2 -2
- package/assets/claude-local/skills/openclaw-skill-importer/SKILL.md +2 -2
- package/assets/claude-local/skills/project-overview-and-strategy/SKILL.md +8 -8
- package/assets/claude-local/skills/published-web-and-mw-core-site/SKILL.md +11 -8
- package/assets/claude-local/skills/standalone-mobile-client/SKILL.md +6 -5
- package/assets/claude-local/skills/vuilder-discovery-output-contract/SKILL.md +6 -6
- package/assets/claude-local/skills/workspace-guidance-refresh/SKILL.md +4 -4
- package/assets/templates/fastapi-sidecar/pyproject.toml +1 -1
- package/assets/templates/fastapi-sidecar/src/fastapi_sidecar/main.py +1 -1
- package/assets/templates/mobile-app/.env.example +4 -4
- package/assets/templates/mobile-app/AGENTS.md +3 -3
- package/assets/templates/mobile-app/README.md +10 -10
- package/assets/templates/mobile-app/app/(app)/_layout.tsx +2 -2
- package/assets/templates/mobile-app/app/(app)/index.tsx +2 -2
- package/assets/templates/mobile-app/app/(auth)/login.tsx +3 -3
- package/assets/templates/mobile-app/app/_layout.tsx +1 -1
- package/assets/templates/mobile-app/babel.config.js +1 -1
- package/assets/templates/mobile-app/eas.json +1 -1
- package/assets/templates/mobile-app/expo-env.d.ts +1 -1
- package/assets/templates/mobile-app/metro.config.js +2 -2
- package/assets/templates/mobile-app/package.json +1 -1
- package/assets/templates/mobile-app/src/mw/client.ts +3 -3
- package/assets/templates/mobile-app/src/mw/contracts.ts +2 -2
- package/assets/templates/mobile-app/src/mw/endpoints.ts +2 -2
- package/assets/templates/mobile-app/src/mw/env.ts +4 -4
- package/assets/templates/mobile-app/src/mw/session.ts +1 -1
- package/assets/templates/mobile-app/template.json +1 -1
- package/assets/templates/mobile-app/tools/template/validate-template.mjs +2 -2
- package/assets/templates/mobile-app/tsconfig.json +1 -1
- package/assets/templates/next-tenant-app/.env.example +1 -1
- package/assets/templates/next-tenant-app/README.md +26 -138
- package/assets/templates/next-tenant-app/package.json +1 -0
- package/assets/templates/next-tenant-app/src/app/app/demo/page.tsx +15 -0
- package/assets/templates/next-tenant-app/src/app/app/layout.tsx +1 -4
- package/assets/templates/next-tenant-app/src/app/app/page.tsx +2 -17
- package/assets/templates/next-tenant-app/src/app/blog/[slug]/page.tsx +9 -67
- package/assets/templates/next-tenant-app/src/app/blog/page.tsx +10 -46
- package/assets/templates/next-tenant-app/src/app/docs/[...slug]/page.tsx +9 -65
- package/assets/templates/next-tenant-app/src/app/docs/page.tsx +10 -46
- package/assets/templates/next-tenant-app/src/app/layout.tsx +8 -10
- package/assets/templates/next-tenant-app/src/app/login/page.tsx +3 -23
- package/assets/templates/next-tenant-app/src/app/page.tsx +11 -44
- package/assets/templates/next-tenant-app/src/app/pricing/page.tsx +10 -44
- package/assets/templates/next-tenant-app/src/app/providers.tsx +2 -1
- package/assets/templates/next-tenant-app/src/app/robots.ts +7 -18
- package/assets/templates/next-tenant-app/src/app/sitemap.ts +4 -39
- package/assets/templates/next-tenant-app/src/features/auth/components/login-screen.tsx +97 -98
- package/assets/templates/next-tenant-app/src/features/dashboard/components/tenant-dashboard.tsx +43 -78
- package/assets/templates/next-tenant-app/src/features/demo/components/manifest-demo.tsx +89 -0
- package/assets/templates/next-tenant-app/src/features/public-shell/components/static-public-page.tsx +58 -0
- package/assets/templates/next-tenant-app/src/features/shell/components/private-app-shell.tsx +48 -552
- package/assets/templates/next-tenant-app/src/lib/app-routes.ts +2 -2
- package/assets/templates/next-tenant-app/src/lib/public-site.test.ts +1 -1
- package/assets/templates/next-tenant-app/src/lib/public-site.ts +5 -30
- package/assets/templates/next-tenant-app/src/mw/client.ts +18 -0
- package/assets/templates/next-tenant-app/src/mw/mock.test.ts +21 -0
- package/assets/templates/next-tenant-app/src/mw/mock.ts +35 -0
- package/assets/templates/next-tenant-app/src/mw/provider.tsx +17 -0
- package/assets/templates/next-tenant-app/template.json +3 -3
- package/assets/templates/next-tenant-app/template.schema.json +1 -0
- package/assets/templates/next-tenant-app/tools/template/validate-route-contract.mjs +4 -5
- package/assets/templates/next-tenant-app/tools/template/with-public-site-fixture.mjs +2 -2
- package/bin/minutework.js +1 -1
- package/dist/agent.js +7 -7
- package/dist/agent.js.map +1 -1
- package/dist/auth.js +7 -7
- package/dist/auth.js.map +1 -1
- package/dist/compile.js +5 -5
- package/dist/config.js +6 -6
- package/dist/config.js.map +1 -1
- package/dist/deploy.js +7 -7
- package/dist/deploy.js.map +1 -1
- package/dist/developer-client.js +2 -2
- package/dist/developer-client.js.map +1 -1
- package/dist/index.js +30 -30
- package/dist/index.js.map +1 -1
- package/dist/init.js +10 -10
- package/dist/init.js.map +1 -1
- package/dist/launcher.js +1 -1
- package/dist/launcher.js.map +1 -1
- package/dist/managed-engine.js +6 -6
- package/dist/managed-engine.js.map +1 -1
- package/dist/orchestrator-context.js +1 -1
- package/dist/orchestrator-context.js.map +1 -1
- package/dist/orchestrator.js +15 -15
- package/dist/orchestrator.js.map +1 -1
- package/dist/paths.js +1 -1
- package/dist/paths.js.map +1 -1
- package/dist/publish.js +3 -3
- package/dist/publish.js.map +1 -1
- package/dist/reporting.js +8 -8
- package/dist/reporting.js.map +1 -1
- package/dist/sandbox.js +5 -5
- package/dist/sandbox.js.map +1 -1
- package/dist/state.js +1 -1
- package/dist/state.js.map +1 -1
- package/dist/tokens.js +9 -9
- package/dist/tokens.js.map +1 -1
- package/dist/workspace-assets.js +6 -6
- package/dist/workspace-assets.js.map +1 -1
- package/dist/workspace.js +3 -3
- package/dist/workspace.js.map +1 -1
- package/package.json +3 -3
- package/vendor/workspace-mcp/context.d.ts +6 -6
- package/vendor/workspace-mcp/context.js +56 -56
- package/vendor/workspace-mcp/context.js.map +1 -1
- package/vendor/workspace-mcp/types.d.ts +4 -0
- package/assets/templates/next-tenant-app/src/app/(cms)/[...path]/page.tsx +0 -89
- package/assets/templates/next-tenant-app/src/app/api/auth/context/route.test.ts +0 -90
- package/assets/templates/next-tenant-app/src/app/api/auth/context/route.ts +0 -78
- package/assets/templates/next-tenant-app/src/app/api/auth/login/route.ts +0 -31
- package/assets/templates/next-tenant-app/src/app/api/auth/logout/route.ts +0 -16
- package/assets/templates/next-tenant-app/src/app/api/auth/password-change/route.test.ts +0 -79
- package/assets/templates/next-tenant-app/src/app/api/auth/password-change/route.ts +0 -40
- package/assets/templates/next-tenant-app/src/app/api/auth/password-status/route.test.ts +0 -42
- package/assets/templates/next-tenant-app/src/app/api/auth/password-status/route.ts +0 -29
- package/assets/templates/next-tenant-app/src/app/api/auth/session/route.ts +0 -26
- package/assets/templates/next-tenant-app/src/app/api/gateway/commands/[runId]/route.test.ts +0 -40
- package/assets/templates/next-tenant-app/src/app/api/gateway/commands/[runId]/route.ts +0 -47
- package/assets/templates/next-tenant-app/src/app/api/gateway/commands/route.test.ts +0 -43
- package/assets/templates/next-tenant-app/src/app/api/gateway/commands/route.ts +0 -45
- package/assets/templates/next-tenant-app/src/app/app/examples/runtime-commands/page.test.ts +0 -83
- package/assets/templates/next-tenant-app/src/app/app/examples/runtime-commands/page.tsx +0 -30
- package/assets/templates/next-tenant-app/src/app/app/page.test.ts +0 -62
- package/assets/templates/next-tenant-app/src/app/app/private-content-source.test.ts +0 -88
- package/assets/templates/next-tenant-app/src/app/blog/[slug]/page.test.ts +0 -70
- package/assets/templates/next-tenant-app/src/app/blog/page.test.ts +0 -46
- package/assets/templates/next-tenant-app/src/app/docs/[...slug]/page.test.ts +0 -70
- package/assets/templates/next-tenant-app/src/app/docs/page.test.ts +0 -46
- package/assets/templates/next-tenant-app/src/app/login/page.test.ts +0 -55
- package/assets/templates/next-tenant-app/src/app/page.test.ts +0 -90
- package/assets/templates/next-tenant-app/src/app/pricing/page.test.ts +0 -59
- package/assets/templates/next-tenant-app/src/app/robots.test.ts +0 -40
- package/assets/templates/next-tenant-app/src/app/sitemap.test.ts +0 -63
- package/assets/templates/next-tenant-app/src/features/examples/runtime-command-demo/components/runtime-command-demo.tsx +0 -342
- package/assets/templates/next-tenant-app/src/features/public-shell/components/content-article.tsx +0 -66
- package/assets/templates/next-tenant-app/src/features/public-shell/components/content-collection.tsx +0 -108
- package/assets/templates/next-tenant-app/src/features/public-shell/components/marketing-page-canvas.tsx +0 -111
- package/assets/templates/next-tenant-app/src/features/public-shell/components/public-site-shell.tsx +0 -111
- package/assets/templates/next-tenant-app/src/features/public-shell/components/section-renderer.test.ts +0 -38
- package/assets/templates/next-tenant-app/src/features/public-shell/components/section-renderer.tsx +0 -145
- package/assets/templates/next-tenant-app/src/lib/content/__fixtures__/public-site-snapshot.ts +0 -189
- package/assets/templates/next-tenant-app/src/lib/content/adapter.server.test.ts +0 -444
- package/assets/templates/next-tenant-app/src/lib/content/adapter.server.ts +0 -383
- package/assets/templates/next-tenant-app/src/lib/content/contracts.test.ts +0 -138
- package/assets/templates/next-tenant-app/src/lib/content/contracts.ts +0 -399
- package/assets/templates/next-tenant-app/src/lib/content/custom-adapter.ts +0 -5
- package/assets/templates/next-tenant-app/src/lib/content/empty-state.ts +0 -96
- package/assets/templates/next-tenant-app/src/lib/content/release-manifest.test.ts +0 -93
- package/assets/templates/next-tenant-app/src/lib/content/release-manifest.ts +0 -123
- package/assets/templates/next-tenant-app/src/lib/platform/auth.server.test.ts +0 -75
- package/assets/templates/next-tenant-app/src/lib/platform/auth.server.ts +0 -25
- package/assets/templates/next-tenant-app/src/lib/platform/client.server.test.ts +0 -170
- package/assets/templates/next-tenant-app/src/lib/platform/client.server.ts +0 -661
- package/assets/templates/next-tenant-app/src/lib/platform/contracts.ts +0 -131
- package/assets/templates/next-tenant-app/src/lib/platform/endpoints.server.ts +0 -34
- package/assets/templates/next-tenant-app/src/lib/platform/env.server.test.ts +0 -211
- package/assets/templates/next-tenant-app/src/lib/platform/env.server.ts +0 -151
- package/assets/templates/next-tenant-app/src/lib/platform/route-response.ts +0 -33
- package/assets/templates/next-tenant-app/src/lib/platform/session.server.ts +0 -108
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
export const commandTemplateKeys = [
|
|
4
|
-
"python_version",
|
|
5
|
-
"echo_hello",
|
|
6
|
-
"system_info",
|
|
7
|
-
"list_apps",
|
|
8
|
-
] as const;
|
|
9
|
-
|
|
10
|
-
export const commandTemplateKeySchema = z.enum(commandTemplateKeys);
|
|
11
|
-
|
|
12
|
-
export const loginRequestSchema = z.object({
|
|
13
|
-
username: z.string().trim().min(1),
|
|
14
|
-
password: z.string().min(1),
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export const sessionMembershipSchema = z.object({
|
|
18
|
-
tenant_id: z.string().min(1),
|
|
19
|
-
tenant_slug: z.string().min(1),
|
|
20
|
-
tenant_name: z.string().min(1),
|
|
21
|
-
role: z.string().min(1),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export const activeTenantSchema = sessionMembershipSchema;
|
|
25
|
-
|
|
26
|
-
export const platformUserSchema = z.object({
|
|
27
|
-
id: z.string().min(1),
|
|
28
|
-
username: z.string().min(1),
|
|
29
|
-
email: z.string().min(1),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
export const upstreamSessionPayloadSchema = z
|
|
33
|
-
.object({
|
|
34
|
-
user: platformUserSchema,
|
|
35
|
-
active_tenant_id: z.string().min(1),
|
|
36
|
-
active_tenant: activeTenantSchema,
|
|
37
|
-
memberships: z.array(sessionMembershipSchema),
|
|
38
|
-
})
|
|
39
|
-
.passthrough();
|
|
40
|
-
|
|
41
|
-
export const anonymousPlatformSessionSchema = z.object({
|
|
42
|
-
authenticated: z.literal(false),
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
export const authenticatedPlatformSessionSchema = z.object({
|
|
46
|
-
authenticated: z.literal(true),
|
|
47
|
-
user: platformUserSchema,
|
|
48
|
-
active_tenant_id: z.string().min(1),
|
|
49
|
-
active_tenant: activeTenantSchema,
|
|
50
|
-
memberships: z.array(sessionMembershipSchema),
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
export const platformSessionSchema = z.union([
|
|
54
|
-
anonymousPlatformSessionSchema,
|
|
55
|
-
authenticatedPlatformSessionSchema,
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
|
-
export const platformErrorPayloadSchema = z
|
|
59
|
-
.object({
|
|
60
|
-
detail: z.string().min(1).optional(),
|
|
61
|
-
error: z.string().min(1).optional(),
|
|
62
|
-
code: z.string().min(1).optional(),
|
|
63
|
-
})
|
|
64
|
-
.passthrough();
|
|
65
|
-
|
|
66
|
-
export const commandDispatchRequestSchema = z.object({
|
|
67
|
-
tenant_id: z.string().min(1),
|
|
68
|
-
template_key: commandTemplateKeySchema,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
export const tenantSessionContextRequestSchema = z.object({
|
|
72
|
-
tenant_id: z.string().min(1),
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
export const passwordStatusSchema = z.object({
|
|
76
|
-
has_password: z.boolean(),
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
export const passwordChangeRequestSchema = z
|
|
80
|
-
.object({
|
|
81
|
-
current_password: z.string().optional().default(""),
|
|
82
|
-
new_password: z.string().min(1),
|
|
83
|
-
confirm_password: z.string().min(1),
|
|
84
|
-
})
|
|
85
|
-
.superRefine((value, context) => {
|
|
86
|
-
if (value.new_password !== value.confirm_password) {
|
|
87
|
-
context.addIssue({
|
|
88
|
-
code: z.ZodIssueCode.custom,
|
|
89
|
-
path: ["confirm_password"],
|
|
90
|
-
message: "Passwords must match.",
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
export const upstreamPasswordChangeRequestSchema = z.object({
|
|
96
|
-
current_password: z.string().optional(),
|
|
97
|
-
new_password: z.string().min(1),
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
export const commandRunSchema = z.object({
|
|
101
|
-
run_id: z.string().min(1),
|
|
102
|
-
tenant_id: z.string().min(1),
|
|
103
|
-
runtime_id: z.string().min(1),
|
|
104
|
-
template_key: z.string().min(1),
|
|
105
|
-
status: z.string().min(1),
|
|
106
|
-
safe_summary: z.string(),
|
|
107
|
-
exit_code: z.number().int().nullable(),
|
|
108
|
-
stdout_tail: z.string(),
|
|
109
|
-
stderr_tail: z.string(),
|
|
110
|
-
source_ref: z.string(),
|
|
111
|
-
dispatch_error: z.string(),
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
export type LoginRequest = z.infer<typeof loginRequestSchema>;
|
|
115
|
-
export type SessionMembership = z.infer<typeof sessionMembershipSchema>;
|
|
116
|
-
export type ActiveTenant = z.infer<typeof activeTenantSchema>;
|
|
117
|
-
export type PlatformUser = z.infer<typeof platformUserSchema>;
|
|
118
|
-
export type PlatformSession = z.infer<typeof platformSessionSchema>;
|
|
119
|
-
export type AuthenticatedPlatformSession = z.infer<
|
|
120
|
-
typeof authenticatedPlatformSessionSchema
|
|
121
|
-
>;
|
|
122
|
-
export type CommandTemplateKey = z.infer<typeof commandTemplateKeySchema>;
|
|
123
|
-
export type CommandDispatchRequest = z.infer<
|
|
124
|
-
typeof commandDispatchRequestSchema
|
|
125
|
-
>;
|
|
126
|
-
export type CommandRun = z.infer<typeof commandRunSchema>;
|
|
127
|
-
export type TenantSessionContextRequest = z.infer<
|
|
128
|
-
typeof tenantSessionContextRequestSchema
|
|
129
|
-
>;
|
|
130
|
-
export type PasswordStatus = z.infer<typeof passwordStatusSchema>;
|
|
131
|
-
export type PasswordChangeRequest = z.infer<typeof passwordChangeRequestSchema>;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import "server-only";
|
|
2
|
-
|
|
3
|
-
import { env } from "@/lib/platform/env.server";
|
|
4
|
-
|
|
5
|
-
const platformBaseUrl = new URL(
|
|
6
|
-
env.MW_PLATFORM_BASE_URL.endsWith("/")
|
|
7
|
-
? env.MW_PLATFORM_BASE_URL
|
|
8
|
-
: `${env.MW_PLATFORM_BASE_URL}/`,
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
function buildPlatformEndpoint(path: string) {
|
|
12
|
-
return new URL(path.replace(/^\//, ""), platformBaseUrl).toString();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const platformAuthEndpoints = {
|
|
16
|
-
login: buildPlatformEndpoint("/api/v1/session/login/"),
|
|
17
|
-
logout: buildPlatformEndpoint("/api/v1/session/logout/"),
|
|
18
|
-
currentSession: buildPlatformEndpoint("/api/v1/session/me/"),
|
|
19
|
-
sessionContext: buildPlatformEndpoint("/api/v1/session/context/"),
|
|
20
|
-
passwordStatus: buildPlatformEndpoint("/api/v1/session/password-status/"),
|
|
21
|
-
passwordChange: buildPlatformEndpoint("/api/v1/session/password-change/"),
|
|
22
|
-
operatorConsole: buildPlatformEndpoint("/ops/login/"),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const platformGatewayEndpoints = {
|
|
26
|
-
tenantCommands: buildPlatformEndpoint("/api/v1/tenant/commands/"),
|
|
27
|
-
tenantCommandRun(runId: string, tenantId: string) {
|
|
28
|
-
const url = new URL(
|
|
29
|
-
buildPlatformEndpoint(`/api/v1/tenant/commands/${encodeURIComponent(runId)}/`),
|
|
30
|
-
);
|
|
31
|
-
url.searchParams.set("tenant_id", tenantId);
|
|
32
|
-
return url.toString();
|
|
33
|
-
},
|
|
34
|
-
};
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
|
|
3
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
4
|
-
|
|
5
|
-
const originalEnv = { ...process.env };
|
|
6
|
-
|
|
7
|
-
function restoreProcessEnv() {
|
|
8
|
-
for (const key of Object.keys(process.env)) {
|
|
9
|
-
if (!(key in originalEnv)) {
|
|
10
|
-
delete process.env[key];
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
Object.assign(process.env, originalEnv);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function applyServerEnv(overrides: Record<string, string | undefined>) {
|
|
18
|
-
restoreProcessEnv();
|
|
19
|
-
process.env.MW_PLATFORM_BASE_URL = "http://127.0.0.1:8000";
|
|
20
|
-
process.env.MW_PUBLIC_CONTENT_SOURCE = "minutework_cms";
|
|
21
|
-
process.env.MW_CONTENT_API_TOKEN = "test-content-token";
|
|
22
|
-
process.env.MW_PUBLIC_BASE_URL = "http://127.0.0.1:3000";
|
|
23
|
-
process.env.MW_PUBLIC_SITE_PROPERTY_KEY = "main-site";
|
|
24
|
-
process.env.MW_ENABLE_RUNTIME_COMMAND_EXAMPLE = "false";
|
|
25
|
-
|
|
26
|
-
for (const [key, value] of Object.entries(overrides)) {
|
|
27
|
-
if (value === undefined) {
|
|
28
|
-
delete process.env[key];
|
|
29
|
-
} else {
|
|
30
|
-
process.env[key] = value;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function readEnvExample() {
|
|
36
|
-
const contents = await readFile(".env.example", "utf8");
|
|
37
|
-
return Object.fromEntries(
|
|
38
|
-
contents
|
|
39
|
-
.split("\n")
|
|
40
|
-
.map((line) => line.trim())
|
|
41
|
-
.filter((line) => line.length > 0 && !line.startsWith("#"))
|
|
42
|
-
.map((line) => {
|
|
43
|
-
const separatorIndex = line.indexOf("=");
|
|
44
|
-
return [
|
|
45
|
-
line.slice(0, separatorIndex),
|
|
46
|
-
line.slice(separatorIndex + 1),
|
|
47
|
-
] as const;
|
|
48
|
-
}),
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
describe("server env", () => {
|
|
53
|
-
afterEach(() => {
|
|
54
|
-
restoreProcessEnv();
|
|
55
|
-
vi.resetModules();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("defaults MW_PUBLIC_SITE_ENV to preview", async () => {
|
|
59
|
-
applyServerEnv({
|
|
60
|
-
MW_PUBLIC_SITE_ENV: undefined,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const { env } = await import("./env.server");
|
|
64
|
-
|
|
65
|
-
expect(env.MW_PUBLIC_SITE_ENV).toBe("preview");
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("defaults MW_PUBLIC_CONTENT_SOURCE to private-only mode", async () => {
|
|
69
|
-
applyServerEnv({
|
|
70
|
-
MW_PUBLIC_CONTENT_SOURCE: undefined,
|
|
71
|
-
MW_CONTENT_API_TOKEN: undefined,
|
|
72
|
-
MW_PUBLIC_BASE_URL: undefined,
|
|
73
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: undefined,
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const { env } = await import("./env.server");
|
|
77
|
-
|
|
78
|
-
expect(env.MW_PUBLIC_CONTENT_SOURCE).toBe("none");
|
|
79
|
-
expect(env.MW_CONTENT_API_TOKEN).toBeUndefined();
|
|
80
|
-
expect(env.MW_PUBLIC_BASE_URL).toBeUndefined();
|
|
81
|
-
expect(env.MW_PUBLIC_SITE_PROPERTY_KEY).toBeUndefined();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("defaults MW_STATIC_PUBLIC_CONTENT_PATH to content/public-site.json", async () => {
|
|
85
|
-
applyServerEnv({
|
|
86
|
-
MW_STATIC_PUBLIC_CONTENT_PATH: undefined,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
const { env } = await import("./env.server");
|
|
90
|
-
|
|
91
|
-
expect(env.MW_STATIC_PUBLIC_CONTENT_PATH).toBe("content/public-site.json");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("accepts MW_PUBLIC_SITE_ENV=live", async () => {
|
|
95
|
-
applyServerEnv({
|
|
96
|
-
MW_PUBLIC_SITE_ENV: "live",
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const { env } = await import("./env.server");
|
|
100
|
-
|
|
101
|
-
expect(env.MW_PUBLIC_SITE_ENV).toBe("live");
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("requires MW_PUBLIC_BASE_URL", async () => {
|
|
105
|
-
applyServerEnv({
|
|
106
|
-
MW_PUBLIC_BASE_URL: undefined,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
await expect(import("./env.server")).rejects.toThrow("MW_PUBLIC_BASE_URL");
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("requires MW_CONTENT_API_TOKEN", async () => {
|
|
113
|
-
applyServerEnv({
|
|
114
|
-
MW_CONTENT_API_TOKEN: undefined,
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
await expect(import("./env.server")).rejects.toThrow("MW_CONTENT_API_TOKEN");
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it("requires MW_PUBLIC_SITE_PROPERTY_KEY", async () => {
|
|
121
|
-
applyServerEnv({
|
|
122
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: undefined,
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
await expect(import("./env.server")).rejects.toThrow(
|
|
126
|
-
"MW_PUBLIC_SITE_PROPERTY_KEY",
|
|
127
|
-
);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("accepts custom public content without PandaWork CMS credentials", async () => {
|
|
131
|
-
applyServerEnv({
|
|
132
|
-
MW_PUBLIC_CONTENT_SOURCE: "custom",
|
|
133
|
-
MW_CONTENT_API_TOKEN: undefined,
|
|
134
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: undefined,
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
const { env } = await import("./env.server");
|
|
138
|
-
|
|
139
|
-
expect(env.MW_PUBLIC_CONTENT_SOURCE).toBe("custom");
|
|
140
|
-
expect(env.MW_CONTENT_API_TOKEN).toBeUndefined();
|
|
141
|
-
expect(env.MW_PUBLIC_SITE_PROPERTY_KEY).toBeUndefined();
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("requires MW_PUBLIC_BASE_URL for custom public content", async () => {
|
|
145
|
-
applyServerEnv({
|
|
146
|
-
MW_PUBLIC_CONTENT_SOURCE: "custom",
|
|
147
|
-
MW_CONTENT_API_TOKEN: undefined,
|
|
148
|
-
MW_PUBLIC_BASE_URL: undefined,
|
|
149
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: undefined,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
await expect(import("./env.server")).rejects.toThrow("MW_PUBLIC_BASE_URL");
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("accepts static JSON public content without PandaWork CMS credentials", async () => {
|
|
156
|
-
applyServerEnv({
|
|
157
|
-
MW_PUBLIC_CONTENT_SOURCE: "static_json",
|
|
158
|
-
MW_CONTENT_API_TOKEN: undefined,
|
|
159
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: undefined,
|
|
160
|
-
MW_STATIC_PUBLIC_CONTENT_PATH: "content/site.json",
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const { env } = await import("./env.server");
|
|
164
|
-
|
|
165
|
-
expect(env.MW_PUBLIC_CONTENT_SOURCE).toBe("static_json");
|
|
166
|
-
expect(env.MW_STATIC_PUBLIC_CONTENT_PATH).toBe("content/site.json");
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it("accepts private-only mode without public or CMS environment", async () => {
|
|
170
|
-
applyServerEnv({
|
|
171
|
-
MW_PUBLIC_CONTENT_SOURCE: "none",
|
|
172
|
-
MW_CONTENT_API_TOKEN: undefined,
|
|
173
|
-
MW_PUBLIC_BASE_URL: undefined,
|
|
174
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: undefined,
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const { env } = await import("./env.server");
|
|
178
|
-
|
|
179
|
-
expect(env.MW_PUBLIC_CONTENT_SOURCE).toBe("none");
|
|
180
|
-
expect(env.MW_PUBLIC_BASE_URL).toBeUndefined();
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it("ships .env.example as private-only so generated apps boot without CMS", async () => {
|
|
184
|
-
await expect(readEnvExample()).resolves.toMatchObject({
|
|
185
|
-
MW_PUBLIC_CONTENT_SOURCE: "none",
|
|
186
|
-
MW_CONTENT_API_TOKEN: "",
|
|
187
|
-
MW_PUBLIC_BASE_URL: "",
|
|
188
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: "",
|
|
189
|
-
MW_STATIC_PUBLIC_CONTENT_PATH: "content/public-site.json",
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it("requires MW_PLATFORM_BASE_URL in production", async () => {
|
|
194
|
-
applyServerEnv({
|
|
195
|
-
MW_PLATFORM_BASE_URL: undefined,
|
|
196
|
-
NODE_ENV: "production",
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
await expect(import("./env.server")).rejects.toThrow(
|
|
200
|
-
"MW_PLATFORM_BASE_URL must be set in production.",
|
|
201
|
-
);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it("rejects unsupported public-site environments", async () => {
|
|
205
|
-
applyServerEnv({
|
|
206
|
-
MW_PUBLIC_SITE_ENV: "draft",
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
await expect(import("./env.server")).rejects.toThrow("MW_PUBLIC_SITE_ENV");
|
|
210
|
-
});
|
|
211
|
-
});
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import "server-only";
|
|
2
|
-
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
|
|
5
|
-
const DEFAULT_LOCAL_PLATFORM_BASE_URL = "http://127.0.0.1:8000";
|
|
6
|
-
const DEFAULT_STATIC_PUBLIC_CONTENT_PATH = "content/public-site.json";
|
|
7
|
-
|
|
8
|
-
const exampleFlagSchema = z.preprocess(
|
|
9
|
-
(value) => value ?? "false",
|
|
10
|
-
z.enum(["true", "false"]).transform((value) => value === "true"),
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
const requiredStringEnvSchema = z.preprocess((value) => {
|
|
14
|
-
if (typeof value !== "string") {
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const normalized = value.trim();
|
|
19
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
20
|
-
}, z.string().min(1));
|
|
21
|
-
|
|
22
|
-
const optionalStringEnvSchema = z.preprocess((value) => {
|
|
23
|
-
if (typeof value !== "string") {
|
|
24
|
-
return value;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const normalized = value.trim();
|
|
28
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
29
|
-
}, z.string().min(1).optional());
|
|
30
|
-
|
|
31
|
-
const optionalUrlEnvSchema = z.preprocess((value) => {
|
|
32
|
-
if (typeof value !== "string") {
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const normalized = value.trim();
|
|
37
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
38
|
-
}, z.string().url().optional());
|
|
39
|
-
|
|
40
|
-
const publicContentSourceSchema = z.enum([
|
|
41
|
-
"minutework_cms",
|
|
42
|
-
"custom",
|
|
43
|
-
"static_json",
|
|
44
|
-
"none",
|
|
45
|
-
]);
|
|
46
|
-
const publicSiteEnvironmentSchema = z.enum(["preview", "live"]);
|
|
47
|
-
|
|
48
|
-
const envSchema = z
|
|
49
|
-
.object({
|
|
50
|
-
MW_PLATFORM_BASE_URL: z.string().url(),
|
|
51
|
-
MW_PUBLIC_CONTENT_SOURCE: z.preprocess(
|
|
52
|
-
(value) => value ?? "none",
|
|
53
|
-
publicContentSourceSchema,
|
|
54
|
-
),
|
|
55
|
-
MW_CONTENT_API_TOKEN: optionalStringEnvSchema,
|
|
56
|
-
MW_TEMPLATE_APP_NAME: z.preprocess(
|
|
57
|
-
(value) => value ?? "PandaWork Combined Starter",
|
|
58
|
-
z.string().trim().min(1),
|
|
59
|
-
),
|
|
60
|
-
MW_PUBLIC_BASE_URL: optionalUrlEnvSchema,
|
|
61
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: optionalStringEnvSchema,
|
|
62
|
-
MW_PUBLIC_SITE_ENV: z.preprocess(
|
|
63
|
-
(value) => value ?? "preview",
|
|
64
|
-
publicSiteEnvironmentSchema,
|
|
65
|
-
),
|
|
66
|
-
MW_STATIC_PUBLIC_CONTENT_PATH: z.preprocess(
|
|
67
|
-
(value) => value ?? DEFAULT_STATIC_PUBLIC_CONTENT_PATH,
|
|
68
|
-
requiredStringEnvSchema,
|
|
69
|
-
),
|
|
70
|
-
MW_ENABLE_RUNTIME_COMMAND_EXAMPLE: exampleFlagSchema,
|
|
71
|
-
NODE_ENV: z
|
|
72
|
-
.enum(["development", "test", "production"])
|
|
73
|
-
.default("development"),
|
|
74
|
-
})
|
|
75
|
-
.superRefine((value, context) => {
|
|
76
|
-
if (value.MW_PUBLIC_CONTENT_SOURCE === "minutework_cms") {
|
|
77
|
-
if (!value.MW_CONTENT_API_TOKEN) {
|
|
78
|
-
context.addIssue({
|
|
79
|
-
code: z.ZodIssueCode.custom,
|
|
80
|
-
path: ["MW_CONTENT_API_TOKEN"],
|
|
81
|
-
message: "Required when MW_PUBLIC_CONTENT_SOURCE=minutework_cms",
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
if (!value.MW_PUBLIC_BASE_URL) {
|
|
85
|
-
context.addIssue({
|
|
86
|
-
code: z.ZodIssueCode.custom,
|
|
87
|
-
path: ["MW_PUBLIC_BASE_URL"],
|
|
88
|
-
message: "Required when MW_PUBLIC_CONTENT_SOURCE=minutework_cms",
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
if (!value.MW_PUBLIC_SITE_PROPERTY_KEY) {
|
|
92
|
-
context.addIssue({
|
|
93
|
-
code: z.ZodIssueCode.custom,
|
|
94
|
-
path: ["MW_PUBLIC_SITE_PROPERTY_KEY"],
|
|
95
|
-
message: "Required when MW_PUBLIC_CONTENT_SOURCE=minutework_cms",
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
(value.MW_PUBLIC_CONTENT_SOURCE === "custom" ||
|
|
102
|
-
value.MW_PUBLIC_CONTENT_SOURCE === "static_json") &&
|
|
103
|
-
!value.MW_PUBLIC_BASE_URL
|
|
104
|
-
) {
|
|
105
|
-
context.addIssue({
|
|
106
|
-
code: z.ZodIssueCode.custom,
|
|
107
|
-
path: ["MW_PUBLIC_BASE_URL"],
|
|
108
|
-
message: `Required when MW_PUBLIC_CONTENT_SOURCE=${value.MW_PUBLIC_CONTENT_SOURCE}`,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const defaultPlatformBaseUrl =
|
|
114
|
-
process.env.MW_PLATFORM_BASE_URL ??
|
|
115
|
-
(process.env.NODE_ENV === "production"
|
|
116
|
-
? undefined
|
|
117
|
-
: DEFAULT_LOCAL_PLATFORM_BASE_URL);
|
|
118
|
-
|
|
119
|
-
const parsedEnv = envSchema.safeParse({
|
|
120
|
-
MW_PLATFORM_BASE_URL: defaultPlatformBaseUrl,
|
|
121
|
-
MW_PUBLIC_CONTENT_SOURCE: process.env.MW_PUBLIC_CONTENT_SOURCE,
|
|
122
|
-
MW_CONTENT_API_TOKEN: process.env.MW_CONTENT_API_TOKEN,
|
|
123
|
-
MW_TEMPLATE_APP_NAME: process.env.MW_TEMPLATE_APP_NAME,
|
|
124
|
-
MW_PUBLIC_BASE_URL: process.env.MW_PUBLIC_BASE_URL,
|
|
125
|
-
MW_PUBLIC_SITE_PROPERTY_KEY: process.env.MW_PUBLIC_SITE_PROPERTY_KEY,
|
|
126
|
-
MW_PUBLIC_SITE_ENV: process.env.MW_PUBLIC_SITE_ENV,
|
|
127
|
-
MW_STATIC_PUBLIC_CONTENT_PATH: process.env.MW_STATIC_PUBLIC_CONTENT_PATH,
|
|
128
|
-
MW_ENABLE_RUNTIME_COMMAND_EXAMPLE:
|
|
129
|
-
process.env.MW_ENABLE_RUNTIME_COMMAND_EXAMPLE,
|
|
130
|
-
NODE_ENV: process.env.NODE_ENV,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
if (!parsedEnv.success) {
|
|
134
|
-
if (
|
|
135
|
-
process.env.NODE_ENV === "production" &&
|
|
136
|
-
!process.env.MW_PLATFORM_BASE_URL
|
|
137
|
-
) {
|
|
138
|
-
throw new Error("MW_PLATFORM_BASE_URL must be set in production.");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const issues = parsedEnv.error.issues
|
|
142
|
-
.map((issue) => {
|
|
143
|
-
const path = issue.path.join(".");
|
|
144
|
-
return path.length > 0 ? `${path}: ${issue.message}` : issue.message;
|
|
145
|
-
})
|
|
146
|
-
.join("; ");
|
|
147
|
-
|
|
148
|
-
throw new Error(`Invalid server environment for next-tenant-app: ${issues}`);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export const env = parsedEnv.data;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
|
|
3
|
-
import { PlatformClientError } from "@/lib/platform/client.server";
|
|
4
|
-
import type { PlatformAuthState } from "@/lib/platform/session.server";
|
|
5
|
-
import { syncPlatformAuthStateToResponse } from "@/lib/platform/session.server";
|
|
6
|
-
|
|
7
|
-
export function toPlatformErrorResponse(
|
|
8
|
-
error: unknown,
|
|
9
|
-
fallbackDetail: string,
|
|
10
|
-
previousAuthState?: PlatformAuthState,
|
|
11
|
-
) {
|
|
12
|
-
if (error instanceof PlatformClientError) {
|
|
13
|
-
const response = NextResponse.json(
|
|
14
|
-
{
|
|
15
|
-
detail: error.message,
|
|
16
|
-
code: error.code,
|
|
17
|
-
},
|
|
18
|
-
{ status: error.status },
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
if (previousAuthState && error.authState) {
|
|
22
|
-
syncPlatformAuthStateToResponse(
|
|
23
|
-
response,
|
|
24
|
-
previousAuthState,
|
|
25
|
-
error.authState,
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return response;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return NextResponse.json({ detail: fallbackDetail }, { status: 500 });
|
|
33
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import "server-only";
|
|
2
|
-
|
|
3
|
-
import { cookies } from "next/headers";
|
|
4
|
-
import type { NextResponse } from "next/server";
|
|
5
|
-
|
|
6
|
-
import { env } from "@/lib/platform/env.server";
|
|
7
|
-
|
|
8
|
-
export const PLATFORM_SESSION_COOKIE = "mw_platform_session";
|
|
9
|
-
export const PLATFORM_CSRF_COOKIE = "mw_platform_csrf";
|
|
10
|
-
|
|
11
|
-
export type PlatformAuthState = {
|
|
12
|
-
sessionId: string | null;
|
|
13
|
-
csrfToken: string | null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function platformCookie(name: string, value: string) {
|
|
17
|
-
return {
|
|
18
|
-
name,
|
|
19
|
-
value,
|
|
20
|
-
httpOnly: true,
|
|
21
|
-
sameSite: "lax" as const,
|
|
22
|
-
path: "/",
|
|
23
|
-
secure: env.NODE_ENV === "production",
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function platformSessionCookie(value: string) {
|
|
28
|
-
return platformCookie(PLATFORM_SESSION_COOKIE, value);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function platformCsrfCookie(value: string) {
|
|
32
|
-
return platformCookie(PLATFORM_CSRF_COOKIE, value);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function readPlatformAuthState(): Promise<PlatformAuthState> {
|
|
36
|
-
const cookieStore = await cookies();
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
sessionId: cookieStore.get(PLATFORM_SESSION_COOKIE)?.value ?? null,
|
|
40
|
-
csrfToken: cookieStore.get(PLATFORM_CSRF_COOKIE)?.value ?? null,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function readPlatformSessionId() {
|
|
45
|
-
return (await readPlatformAuthState()).sessionId;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function readPlatformCsrfToken() {
|
|
49
|
-
return (await readPlatformAuthState()).csrfToken;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function applyPlatformSessionToResponse(
|
|
53
|
-
response: NextResponse,
|
|
54
|
-
sessionId: string,
|
|
55
|
-
) {
|
|
56
|
-
response.cookies.set(platformSessionCookie(sessionId));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function applyPlatformCsrfToResponse(
|
|
60
|
-
response: NextResponse,
|
|
61
|
-
csrfToken: string,
|
|
62
|
-
) {
|
|
63
|
-
response.cookies.set(platformCsrfCookie(csrfToken));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function applyPlatformAuthStateToResponse(
|
|
67
|
-
response: NextResponse,
|
|
68
|
-
authState: PlatformAuthState,
|
|
69
|
-
) {
|
|
70
|
-
if (authState.sessionId) {
|
|
71
|
-
applyPlatformSessionToResponse(response, authState.sessionId);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (authState.csrfToken) {
|
|
75
|
-
applyPlatformCsrfToResponse(response, authState.csrfToken);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function syncPlatformAuthStateToResponse(
|
|
80
|
-
response: NextResponse,
|
|
81
|
-
previousAuthState: PlatformAuthState,
|
|
82
|
-
nextAuthState: PlatformAuthState,
|
|
83
|
-
) {
|
|
84
|
-
if (previousAuthState.sessionId !== nextAuthState.sessionId) {
|
|
85
|
-
if (nextAuthState.sessionId) {
|
|
86
|
-
applyPlatformSessionToResponse(response, nextAuthState.sessionId);
|
|
87
|
-
} else {
|
|
88
|
-
response.cookies.delete(PLATFORM_SESSION_COOKIE);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (previousAuthState.csrfToken !== nextAuthState.csrfToken) {
|
|
93
|
-
if (nextAuthState.csrfToken) {
|
|
94
|
-
applyPlatformCsrfToResponse(response, nextAuthState.csrfToken);
|
|
95
|
-
} else {
|
|
96
|
-
response.cookies.delete(PLATFORM_CSRF_COOKIE);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function clearPlatformSessionFromResponse(response: NextResponse) {
|
|
102
|
-
response.cookies.delete(PLATFORM_SESSION_COOKIE);
|
|
103
|
-
response.cookies.delete(PLATFORM_CSRF_COOKIE);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function clearPlatformCsrfFromResponse(response: NextResponse) {
|
|
107
|
-
response.cookies.delete(PLATFORM_CSRF_COOKIE);
|
|
108
|
-
}
|