@treasuryspatial/surface-kit 0.1.1 → 0.1.3

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/index.d.ts CHANGED
@@ -88,6 +88,7 @@ export type ResolvedSurfaceBrandingImages = {
88
88
  subtenantLogo: UiManifestImage | null;
89
89
  scaffoldPrimaryLogo: UiManifestImage | null;
90
90
  };
91
+ export type SurfaceBrandingImageMapper = (src: string) => string | null | undefined;
91
92
  export declare const DEFAULT_MARKETING_SLUGS: string[];
92
93
  export declare const TREASURY_LOGO: {
93
94
  src: string;
@@ -100,6 +101,7 @@ export declare const TRANSITGUY_LOGO: {
100
101
  export declare const normalizeSurfaceBrandingPayload: (raw: unknown) => SurfaceBrandingPayload | null;
101
102
  export declare const resolveSurfaceBrandingImages: (target: SurfaceBrandingTarget, payload?: SurfaceBrandingPayload | null) => ResolvedSurfaceBrandingImages;
102
103
  export declare const applySurfaceBrandingToManifest: (manifest: UiManifest, payload?: SurfaceBrandingPayload | null) => UiManifest;
104
+ export declare const mapSurfaceBrandingManifestImages: (manifest: UiManifest, mapSrc: SurfaceBrandingImageMapper) => UiManifest;
103
105
  export declare const SURFACE_KITS: Record<SurfaceKitId, SurfaceKitProfile>;
104
106
  export declare const SURFACE_SKINS: Record<string, SurfaceSkinProfile>;
105
107
  export declare const SURFACE_HOST_PRESETS: Record<string, SurfaceHostPreset>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,6 +20,17 @@ const buildManifestImage = (src, alt) => {
20
20
  return null;
21
21
  return { src, alt };
22
22
  };
23
+ const mapManifestImage = (image, mapSrc) => {
24
+ if (!image?.src)
25
+ return undefined;
26
+ const mappedSrc = mapSrc(image.src);
27
+ if (!mappedSrc || mappedSrc === image.src)
28
+ return image;
29
+ return {
30
+ ...image,
31
+ src: mappedSrc,
32
+ };
33
+ };
23
34
  const cloneRecord = (value) => {
24
35
  if (!value || typeof value !== 'object' || Array.isArray(value))
25
36
  return null;
@@ -158,6 +169,41 @@ export const applySurfaceBrandingToManifest = (manifest, payload) => {
158
169
  : nextSurface,
159
170
  };
160
171
  };
172
+ export const mapSurfaceBrandingManifestImages = (manifest, mapSrc) => {
173
+ const mappedTopbarLogo = mapManifestImage(manifest.topbar.logo, mapSrc);
174
+ const mappedSubtenantLogo = mapManifestImage(manifest.topbar.subtenantLogo, mapSrc);
175
+ const mappedSecondaryLogo = mapManifestImage(manifest.topbar.secondaryLogo, mapSrc);
176
+ const mappedPrimaryShellLogo = mapManifestImage(manifest.surface?.scaffoldShell?.primaryLogo, mapSrc);
177
+ const mappedSecondaryShellLogo = mapManifestImage(manifest.surface?.scaffoldShell?.secondaryLogo, mapSrc);
178
+ if (mappedTopbarLogo === manifest.topbar.logo &&
179
+ mappedSubtenantLogo === manifest.topbar.subtenantLogo &&
180
+ mappedSecondaryLogo === manifest.topbar.secondaryLogo &&
181
+ mappedPrimaryShellLogo === manifest.surface?.scaffoldShell?.primaryLogo &&
182
+ mappedSecondaryShellLogo === manifest.surface?.scaffoldShell?.secondaryLogo) {
183
+ return manifest;
184
+ }
185
+ return {
186
+ ...manifest,
187
+ topbar: {
188
+ ...manifest.topbar,
189
+ logo: mappedTopbarLogo,
190
+ subtenantLogo: mappedSubtenantLogo,
191
+ secondaryLogo: mappedSecondaryLogo,
192
+ },
193
+ surface: manifest.surface
194
+ ? {
195
+ ...manifest.surface,
196
+ scaffoldShell: manifest.surface.scaffoldShell
197
+ ? {
198
+ ...manifest.surface.scaffoldShell,
199
+ primaryLogo: mappedPrimaryShellLogo,
200
+ secondaryLogo: mappedSecondaryShellLogo,
201
+ }
202
+ : manifest.surface.scaffoldShell,
203
+ }
204
+ : manifest.surface,
205
+ };
206
+ };
161
207
  const TRANSIT_MODE_POLICY = mergeSurfaceModePolicy(DEFAULT_COMPOSER_SURFACE_MODE_POLICY, {
162
208
  defaultMode: 'streetmix',
163
209
  modes: {
@@ -0,0 +1,243 @@
1
+ import { NextResponse, type NextRequest } from 'next/server.js';
2
+ import type { UiManifest } from '@treasuryspatial/ui-manifest';
3
+ import { type SurfaceBrandingPayload, type SurfaceHostContext } from './index.js';
4
+ export declare const SURFACE_AUTH_COOKIE_NAME = "treasury_auth_token";
5
+ export type HeaderBag = {
6
+ get(name: string): string | null | undefined;
7
+ };
8
+ export type AssetTokenRequest = {
9
+ scope: string[];
10
+ prefix?: string;
11
+ ttl?: number;
12
+ audience?: string;
13
+ };
14
+ export type AssetTokenResponse = {
15
+ token: string;
16
+ expiresIn?: number;
17
+ expiresAt?: string;
18
+ };
19
+ export type AssetTokenRequester = (payload: AssetTokenRequest) => Promise<AssetTokenResponse>;
20
+ export type BrandingAssetCookie = {
21
+ name: string;
22
+ value: string;
23
+ maxAge: number;
24
+ secure: boolean;
25
+ sameSite: 'none' | 'lax';
26
+ domain?: string;
27
+ path: '/';
28
+ };
29
+ export type SurfaceMembership = {
30
+ tenantId?: string;
31
+ tenant_id?: string;
32
+ slug?: string;
33
+ tenantSlug?: string;
34
+ tenantName?: string;
35
+ membershipType?: string;
36
+ membership_type?: string;
37
+ productScopes?: string[];
38
+ roles?: string[];
39
+ };
40
+ type SurfacePermissions = {
41
+ isSuperAdmin?: boolean;
42
+ canManageTenants?: boolean;
43
+ canManageUsers?: boolean;
44
+ };
45
+ export type SurfaceAuthUser = {
46
+ email?: string | null;
47
+ displayName?: string | null;
48
+ givenName?: string | null;
49
+ familyName?: string | null;
50
+ memberships?: SurfaceMembership[];
51
+ subtenant?: {
52
+ slug?: string | null;
53
+ } | null;
54
+ subtenantSlug?: string | null;
55
+ permissions?: SurfacePermissions | null;
56
+ };
57
+ export type SurfaceRequestContext = {
58
+ host: string;
59
+ surfaceContext: SurfaceHostContext;
60
+ };
61
+ export type SurfaceServerFetchOptions = {
62
+ adminApiUrl?: string;
63
+ fetchImpl?: typeof fetch;
64
+ timeoutMs?: number;
65
+ };
66
+ export type SurfaceBootstrapOptions = SurfaceServerFetchOptions & {
67
+ headers: HeaderBag;
68
+ surfaceContext: SurfaceHostContext;
69
+ manifest?: UiManifest | null;
70
+ brandingPayload?: unknown;
71
+ requestAssetToken?: AssetTokenRequester;
72
+ assetScope?: string[];
73
+ assetPrefix?: string;
74
+ assetTtl?: number;
75
+ assetAudience?: string;
76
+ };
77
+ export type SurfaceBootstrapResult = {
78
+ branding: SurfaceBrandingPayload | null;
79
+ manifest: UiManifest | null;
80
+ assetCookie: BrandingAssetCookie | null;
81
+ };
82
+ export type SurfaceSessionValidation = {
83
+ valid: boolean;
84
+ authorized: boolean;
85
+ user: SurfaceAuthUser | null;
86
+ membership: SurfaceMembership | null;
87
+ payload: Record<string, unknown> | null;
88
+ };
89
+ export type SurfaceBrowserSession = {
90
+ browserToken: string;
91
+ user: SurfaceAuthUser | null;
92
+ membership: SurfaceMembership;
93
+ surfaceContext: SurfaceHostContext;
94
+ };
95
+ export type SurfaceBrowserSessionOptions = SurfaceServerFetchOptions & {
96
+ email: string;
97
+ password: string;
98
+ surfaceContext: SurfaceHostContext;
99
+ };
100
+ export type SurfaceCookieWriter = {
101
+ set: (name: string, value: string, options?: {
102
+ httpOnly?: boolean;
103
+ sameSite?: 'lax' | 'strict' | 'none';
104
+ secure?: boolean;
105
+ maxAge?: number;
106
+ domain?: string;
107
+ path?: string;
108
+ }) => void;
109
+ };
110
+ export type SurfaceCookieReader = {
111
+ get(name: string): {
112
+ value?: string;
113
+ } | undefined;
114
+ };
115
+ export type CreateSurfaceMiddlewareOptions = SurfaceServerFetchOptions & {
116
+ resolveSurfaceHostContext: (host?: string | null) => SurfaceHostContext;
117
+ requestAssetToken?: AssetTokenRequester;
118
+ bypass?: (pathname: string, surfaceContext: SurfaceHostContext) => boolean;
119
+ allowUnauthenticated?: (pathname: string, surfaceContext: SurfaceHostContext) => boolean;
120
+ attachBrandingCookie?: (pathname: string, surfaceContext: SurfaceHostContext) => boolean;
121
+ loginPath?: string;
122
+ clearCookieNames?: string[];
123
+ redirectAuthenticatedFromLogin?: (request: NextRequest, surfaceContext: SurfaceHostContext) => URL;
124
+ redirectUnauthenticated?: (request: NextRequest, surfaceContext: SurfaceHostContext) => URL;
125
+ redirectUnauthorized?: (request: NextRequest, surfaceContext: SurfaceHostContext) => URL;
126
+ onAuthorized?: (request: NextRequest, validation: SurfaceSessionValidation, surfaceContext: SurfaceHostContext) => Promise<NextResponse | null | undefined> | NextResponse | null | undefined;
127
+ };
128
+ export declare class SurfaceBrowserSessionError extends Error {
129
+ status: number;
130
+ constructor(status: number, message: string);
131
+ }
132
+ export declare const normalizeRequestHost: (value?: string | null) => string;
133
+ export declare const resolveRequestHost: (headers: HeaderBag) => string;
134
+ export declare const resolveSurfaceRequestContext: (requestOrHeaders: NextRequest | HeaderBag, resolveSurfaceHostContext: (host?: string | null) => SurfaceHostContext) => SurfaceRequestContext;
135
+ export declare const resolveAdminApiUrl: (pathname: string, explicitBase?: string) => string;
136
+ export declare const resolveTenantLookupSlug: (surfaceContext: SurfaceHostContext) => string;
137
+ export declare const fetchSurfaceTenant: (surfaceContext: SurfaceHostContext, options?: SurfaceServerFetchOptions & {
138
+ view?: string;
139
+ }) => Promise<any>;
140
+ export declare const fetchSurfaceBranding: (surfaceContext: SurfaceHostContext, options?: SurfaceServerFetchOptions) => Promise<any>;
141
+ export declare const resolveSurfaceBranding: (raw: unknown, fallbackSlug: string, isMarketingSlug?: (slug?: string | null) => boolean) => {
142
+ slug: string;
143
+ invalidSubdomain: boolean;
144
+ isEnvironment: boolean;
145
+ tenant?: {
146
+ displayName?: string | null;
147
+ } | null;
148
+ logos?: {
149
+ primary?: string | null;
150
+ [key: string]: unknown;
151
+ } | null;
152
+ organization?: {
153
+ logoUrl?: string | null;
154
+ } | null;
155
+ subtenant?: {
156
+ slug?: string | null;
157
+ name?: string | null;
158
+ logoUrl?: string | null;
159
+ logo_url?: string | null;
160
+ logos?: {
161
+ primary?: string | null;
162
+ [key: string]: unknown;
163
+ } | null;
164
+ branding?: {
165
+ name?: string | null;
166
+ logos?: {
167
+ primary?: string | null;
168
+ [key: string]: unknown;
169
+ } | null;
170
+ colors?: Record<string, string> | null;
171
+ typography?: Record<string, string> | null;
172
+ theme?: Record<string, string> | null;
173
+ } | null;
174
+ } | null;
175
+ branding?: {
176
+ name?: string | null;
177
+ logos?: {
178
+ primary?: string | null;
179
+ [key: string]: unknown;
180
+ } | null;
181
+ colors?: Record<string, string> | null;
182
+ typography?: Record<string, string> | null;
183
+ theme?: Record<string, string> | null;
184
+ } | null;
185
+ logoUrl?: string | null;
186
+ logo_url?: string | null;
187
+ } | null;
188
+ export declare const findSurfaceMembership: (memberships: SurfaceMembership[] | undefined, tenantSlug: string) => SurfaceMembership | undefined;
189
+ export declare const buildAdminAuthSelection: (surfaceContext: SurfaceHostContext) => {
190
+ tenantId: string;
191
+ requestedSubtenantSlug: string;
192
+ } | {
193
+ tenantId: string;
194
+ requestedSubtenantSlug?: undefined;
195
+ };
196
+ export declare const resolveSurfaceAccess: (user: SurfaceAuthUser | null | undefined, surfaceContext: SurfaceHostContext) => {
197
+ authorized: boolean;
198
+ membership: SurfaceMembership | null;
199
+ };
200
+ export declare const readSurfaceAuthToken: (cookies: SurfaceCookieReader) => string | null;
201
+ export declare const writeSurfaceAuthCookie: (cookies: SurfaceCookieWriter, token: string, options: {
202
+ secure: boolean;
203
+ maxAge: number;
204
+ path?: string;
205
+ domain?: string;
206
+ }) => void;
207
+ export declare const clearSurfaceAuthCookie: (cookies: SurfaceCookieWriter, path?: string) => void;
208
+ export declare const resolveSecureCookie: (forwardedProto: string | null, protocol: string) => boolean;
209
+ export declare const validateSurfaceBrowserSession: ({ token, surfaceContext, fetchImpl, adminApiUrl, }: SurfaceServerFetchOptions & {
210
+ token: string;
211
+ surfaceContext: SurfaceHostContext;
212
+ }) => Promise<SurfaceSessionValidation>;
213
+ export declare const exchangeSurfaceBrowserSession: ({ email, password, surfaceContext, fetchImpl, adminApiUrl, }: SurfaceBrowserSessionOptions) => Promise<SurfaceBrowserSession>;
214
+ export declare const shouldSignSurfaceBrandingAsset: (logoUrl: string | null) => boolean;
215
+ export declare const resolveBrandingAssetCookieOptions: (headers: HeaderBag) => {
216
+ name: string;
217
+ domain: string | undefined;
218
+ sameSite: "none" | "lax";
219
+ secure: boolean;
220
+ };
221
+ export declare const buildBrandingAssetCookie: ({ headers, logoUrl, requestAssetToken, assetScope, assetPrefix, assetTtl, assetAudience, }: {
222
+ headers: HeaderBag;
223
+ logoUrl: string | null;
224
+ requestAssetToken: AssetTokenRequester;
225
+ assetScope?: string[];
226
+ assetPrefix?: string;
227
+ assetTtl?: number;
228
+ assetAudience?: string;
229
+ }) => Promise<BrandingAssetCookie | null>;
230
+ export declare const buildSurfaceBrandingAssetCookie: ({ headers, surfaceContext, requestAssetToken, assetScope, assetPrefix, assetTtl, assetAudience, ...fetchOptions }: SurfaceServerFetchOptions & {
231
+ headers: HeaderBag;
232
+ surfaceContext: SurfaceHostContext;
233
+ requestAssetToken: AssetTokenRequester;
234
+ assetScope?: string[];
235
+ assetPrefix?: string;
236
+ assetTtl?: number;
237
+ assetAudience?: string;
238
+ }) => Promise<BrandingAssetCookie | null>;
239
+ export declare const bootstrapSurfaceBranding: ({ headers, surfaceContext, manifest, brandingPayload, requestAssetToken, assetScope, assetPrefix, assetTtl, assetAudience, ...fetchOptions }: SurfaceBootstrapOptions) => Promise<SurfaceBootstrapResult>;
240
+ export declare const isSurfaceStaticBypassPath: (pathname: string, extraPrefixes?: string[]) => boolean;
241
+ export declare const createSurfaceMiddleware: ({ resolveSurfaceHostContext, requestAssetToken, bypass, allowUnauthenticated, attachBrandingCookie, loginPath, clearCookieNames, redirectAuthenticatedFromLogin, redirectUnauthenticated, redirectUnauthorized, onAuthorized, ...fetchOptions }: CreateSurfaceMiddlewareOptions) => (request: NextRequest) => Promise<NextResponse<unknown>>;
242
+ export {};
243
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js ADDED
@@ -0,0 +1,426 @@
1
+ import { NextResponse } from 'next/server.js';
2
+ import { applySurfaceBrandingToManifest, normalizeSurfaceBrandingPayload, } from './index.js';
3
+ export const SURFACE_AUTH_COOKIE_NAME = 'treasury_auth_token';
4
+ const DEFAULT_ADMIN_API_URL = 'https://admin-api.treasury.space/api';
5
+ const DEFAULT_BRANDING_SCOPE = ['admin'];
6
+ const DEFAULT_BRANDING_PREFIX = 'admin';
7
+ const DEFAULT_BRANDING_TTL = 600;
8
+ const DEFAULT_BRANDING_AUDIENCE = 'assets';
9
+ const DEFAULT_BYPASS_EXACT = new Set(['/favicon.ico', '/robots.txt', '/sitemap.xml']);
10
+ const DEFAULT_BYPASS_PREFIXES = ['/_next', '/fonts', '/textures'];
11
+ const DEFAULT_BYPASS_PATTERN = /\.(?:css|js|map|ico|png|jpg|jpeg|gif|svg|webp|avif|woff2?|ttf|otf|eot|wasm|json|txt|xml|csv)$/i;
12
+ const readEnv = (...values) => {
13
+ for (const value of values) {
14
+ const trimmed = value?.trim();
15
+ if (trimmed)
16
+ return trimmed;
17
+ }
18
+ return '';
19
+ };
20
+ const normalizeTenant = (value) => String(value || '').trim().toLowerCase();
21
+ const isLocalUrl = (value) => value.includes('localhost') || value.includes('127.0.0.1');
22
+ const buildServiceAuthHeaders = () => {
23
+ const serviceToken = readEnv(process.env.TREASURY_SERVICE_TOKEN);
24
+ const headers = {
25
+ Accept: 'application/json',
26
+ };
27
+ if (serviceToken) {
28
+ headers.Authorization = `TreasuryService ${serviceToken}`;
29
+ }
30
+ return headers;
31
+ };
32
+ const fetchJson = async (url, { fetchImpl = fetch, timeoutMs = 2500, } = {}) => {
33
+ const controller = new AbortController();
34
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
35
+ try {
36
+ const response = await fetchImpl(url, {
37
+ signal: controller.signal,
38
+ cache: 'no-store',
39
+ headers: buildServiceAuthHeaders(),
40
+ });
41
+ if (!response.ok)
42
+ return null;
43
+ return response.json();
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ finally {
49
+ clearTimeout(timeoutId);
50
+ }
51
+ };
52
+ export class SurfaceBrowserSessionError extends Error {
53
+ status;
54
+ constructor(status, message) {
55
+ super(message);
56
+ this.status = status;
57
+ }
58
+ }
59
+ export const normalizeRequestHost = (value) => (value || '')
60
+ .split(',')[0]
61
+ .trim()
62
+ .toLowerCase()
63
+ .replace(/:\d+$/, '');
64
+ export const resolveRequestHost = (headers) => normalizeRequestHost(headers.get('x-forwarded-host') || headers.get('host'));
65
+ export const resolveSurfaceRequestContext = (requestOrHeaders, resolveSurfaceHostContext) => {
66
+ const headers = 'headers' in requestOrHeaders ? requestOrHeaders.headers : requestOrHeaders;
67
+ const host = resolveRequestHost(headers);
68
+ return {
69
+ host,
70
+ surfaceContext: resolveSurfaceHostContext(host),
71
+ };
72
+ };
73
+ export const resolveAdminApiUrl = (pathname, explicitBase) => {
74
+ const rawBase = explicitBase ||
75
+ process.env.ADMIN_API_URL ||
76
+ process.env.ADMIN_API_BASE_URL ||
77
+ process.env.NEXT_PUBLIC_ADMIN_API_URL ||
78
+ DEFAULT_ADMIN_API_URL;
79
+ const base = rawBase.replace(/\/+$/, '');
80
+ if (base.endsWith('/api'))
81
+ return `${base}${pathname}`;
82
+ return `${base}/api${pathname}`;
83
+ };
84
+ const getAdminCandidates = (explicitBase) => {
85
+ const baseUrl = resolveAdminApiUrl('', explicitBase).replace(/\/$/, '');
86
+ if (isLocalUrl(baseUrl) && baseUrl !== DEFAULT_ADMIN_API_URL) {
87
+ return [baseUrl, DEFAULT_ADMIN_API_URL];
88
+ }
89
+ return [baseUrl];
90
+ };
91
+ export const resolveTenantLookupSlug = (surfaceContext) => surfaceContext.subtenantSlug ? surfaceContext.tenantSlug : surfaceContext.effectiveTenantSlug;
92
+ export const fetchSurfaceTenant = async (surfaceContext, options = {}) => {
93
+ const slug = resolveTenantLookupSlug(surfaceContext);
94
+ const subtenantQuery = surfaceContext.subtenantSlug
95
+ ? `&subtenantSlug=${encodeURIComponent(surfaceContext.subtenantSlug)}`
96
+ : '';
97
+ for (const baseUrl of getAdminCandidates(options.adminApiUrl)) {
98
+ const url = `${baseUrl}/tenants/${encodeURIComponent(slug)}?view=${encodeURIComponent(options.view ?? 'composer')}${subtenantQuery}`;
99
+ const payload = await fetchJson(url, options);
100
+ if (payload)
101
+ return payload;
102
+ }
103
+ return null;
104
+ };
105
+ export const fetchSurfaceBranding = async (surfaceContext, options = {}) => {
106
+ const slug = resolveTenantLookupSlug(surfaceContext);
107
+ const subtenantQuery = surfaceContext.subtenantSlug
108
+ ? `?subtenantSlug=${encodeURIComponent(surfaceContext.subtenantSlug)}`
109
+ : '';
110
+ for (const baseUrl of getAdminCandidates(options.adminApiUrl)) {
111
+ const urls = slug
112
+ ? [
113
+ `${baseUrl}/branding/${encodeURIComponent(slug)}${subtenantQuery}`,
114
+ `${baseUrl}/platform/branding?tenantId=${encodeURIComponent(slug)}${surfaceContext.subtenantSlug
115
+ ? `&subtenantSlug=${encodeURIComponent(surfaceContext.subtenantSlug)}`
116
+ : ''}`,
117
+ ]
118
+ : [`${baseUrl}/branding`];
119
+ for (const url of urls) {
120
+ const payload = await fetchJson(url, options);
121
+ if (payload)
122
+ return payload;
123
+ }
124
+ }
125
+ return null;
126
+ };
127
+ export const resolveSurfaceBranding = (raw, fallbackSlug, isMarketingSlug) => {
128
+ const payload = normalizeSurfaceBrandingPayload(raw) ?? null;
129
+ const source = raw && typeof raw === 'object' && !Array.isArray(raw) && 'data' in raw && raw.data
130
+ ? raw.data
131
+ : (raw ?? {});
132
+ const slug = normalizeTenant(source?.slug || source?.tenant?.slug || fallbackSlug);
133
+ return payload
134
+ ? {
135
+ ...payload,
136
+ slug: slug || fallbackSlug,
137
+ invalidSubdomain: source?.invalidSubdomain ?? payload.invalidSubdomain ?? false,
138
+ isEnvironment: isMarketingSlug ? isMarketingSlug(slug || fallbackSlug) : payload.isEnvironment ?? false,
139
+ }
140
+ : null;
141
+ };
142
+ export const findSurfaceMembership = (memberships = [], tenantSlug) => {
143
+ const target = normalizeTenant(tenantSlug);
144
+ return memberships.find((membership) => {
145
+ const membershipTenant = normalizeTenant(membership.tenantSlug || membership.slug || membership.tenantId || membership.tenant_id);
146
+ return membershipTenant === target;
147
+ });
148
+ };
149
+ const isPrivilegedUser = (user) => Boolean(user?.permissions?.isSuperAdmin ||
150
+ user?.permissions?.canManageTenants ||
151
+ user?.permissions?.canManageUsers);
152
+ export const buildAdminAuthSelection = (surfaceContext) => {
153
+ const tenantId = surfaceContext.subtenantSlug
154
+ ? surfaceContext.tenantSlug
155
+ : surfaceContext.effectiveTenantSlug;
156
+ return surfaceContext.subtenantSlug
157
+ ? {
158
+ tenantId,
159
+ requestedSubtenantSlug: surfaceContext.subtenantSlug,
160
+ }
161
+ : { tenantId };
162
+ };
163
+ export const resolveSurfaceAccess = (user, surfaceContext) => {
164
+ const memberships = Array.isArray(user?.memberships) ? user.memberships : [];
165
+ const canonicalMembership = findSurfaceMembership(memberships, surfaceContext.tenantSlug);
166
+ const compatibilityMembership = findSurfaceMembership(memberships, surfaceContext.effectiveTenantSlug);
167
+ const requestedSubtenantSlug = normalizeTenant(surfaceContext.subtenantSlug);
168
+ const resolvedSubtenantSlug = normalizeTenant(user?.subtenantSlug || user?.subtenant?.slug);
169
+ if (!requestedSubtenantSlug) {
170
+ const membership = canonicalMembership || compatibilityMembership || null;
171
+ return { authorized: Boolean(membership), membership };
172
+ }
173
+ if (resolvedSubtenantSlug && resolvedSubtenantSlug === requestedSubtenantSlug) {
174
+ const membership = canonicalMembership || compatibilityMembership || null;
175
+ return { authorized: Boolean(membership), membership };
176
+ }
177
+ if (compatibilityMembership) {
178
+ return { authorized: true, membership: compatibilityMembership };
179
+ }
180
+ if (canonicalMembership && isPrivilegedUser(user)) {
181
+ return { authorized: true, membership: canonicalMembership };
182
+ }
183
+ return {
184
+ authorized: false,
185
+ membership: canonicalMembership || compatibilityMembership || null,
186
+ };
187
+ };
188
+ export const readSurfaceAuthToken = (cookies) => cookies.get(SURFACE_AUTH_COOKIE_NAME)?.value?.trim() || null;
189
+ export const writeSurfaceAuthCookie = (cookies, token, options) => {
190
+ cookies.set(SURFACE_AUTH_COOKIE_NAME, token, {
191
+ httpOnly: true,
192
+ sameSite: 'lax',
193
+ secure: options.secure,
194
+ maxAge: options.maxAge,
195
+ domain: options.domain,
196
+ path: options.path || '/',
197
+ });
198
+ };
199
+ export const clearSurfaceAuthCookie = (cookies, path = '/') => {
200
+ cookies.set(SURFACE_AUTH_COOKIE_NAME, '', { path, maxAge: 0 });
201
+ };
202
+ export const resolveSecureCookie = (forwardedProto, protocol) => forwardedProto ? forwardedProto === 'https' : protocol === 'https:';
203
+ export const validateSurfaceBrowserSession = async ({ token, surfaceContext, fetchImpl = fetch, adminApiUrl, }) => {
204
+ try {
205
+ const response = await fetchImpl(resolveAdminApiUrl('/auth/validate', adminApiUrl), {
206
+ method: 'POST',
207
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
208
+ body: JSON.stringify({ token, ...buildAdminAuthSelection(surfaceContext) }),
209
+ cache: 'no-store',
210
+ });
211
+ const payload = (await response.json().catch(() => null));
212
+ const valid = Boolean(payload?.valid ?? payload?.success);
213
+ if (!response.ok || !valid) {
214
+ return { valid: false, authorized: false, user: null, membership: null, payload };
215
+ }
216
+ const user = payload?.user ?? null;
217
+ const access = resolveSurfaceAccess(user, surfaceContext);
218
+ return {
219
+ valid: Boolean(access.authorized && access.membership),
220
+ authorized: access.authorized,
221
+ user,
222
+ membership: access.membership,
223
+ payload,
224
+ };
225
+ }
226
+ catch {
227
+ return { valid: false, authorized: false, user: null, membership: null, payload: null };
228
+ }
229
+ };
230
+ export const exchangeSurfaceBrowserSession = async ({ email, password, surfaceContext, fetchImpl = fetch, adminApiUrl, }) => {
231
+ let response;
232
+ try {
233
+ response = await fetchImpl(resolveAdminApiUrl('/auth/login', adminApiUrl), {
234
+ method: 'POST',
235
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
236
+ body: JSON.stringify({ email, password, ...buildAdminAuthSelection(surfaceContext) }),
237
+ cache: 'no-store',
238
+ });
239
+ }
240
+ catch (error) {
241
+ throw new SurfaceBrowserSessionError(502, `Admin auth bridge failed: ${error?.message || 'fetch failed'}`);
242
+ }
243
+ const payload = (await response.json().catch(() => null));
244
+ const missingBrowserToken = payload?.success && !payload?.browserToken;
245
+ if (!response.ok || !payload?.success || missingBrowserToken) {
246
+ throw new SurfaceBrowserSessionError(missingBrowserToken ? 502 : response.status || 401, payload?.error || (missingBrowserToken ? 'Admin login response missing browserToken' : 'Invalid credentials'));
247
+ }
248
+ const user = payload.user ?? null;
249
+ const access = resolveSurfaceAccess(user, surfaceContext);
250
+ if (!access.authorized || !access.membership) {
251
+ throw new SurfaceBrowserSessionError(403, 'Account not enabled for this Treasury tenant');
252
+ }
253
+ return {
254
+ browserToken: payload.browserToken,
255
+ user,
256
+ membership: access.membership,
257
+ surfaceContext,
258
+ };
259
+ };
260
+ export const shouldSignSurfaceBrandingAsset = (logoUrl) => {
261
+ if (!logoUrl)
262
+ return false;
263
+ try {
264
+ const parsed = new URL(logoUrl);
265
+ return parsed.hostname === 'assets.treasury.space' && parsed.pathname.toLowerCase().startsWith('/admin/');
266
+ }
267
+ catch {
268
+ return false;
269
+ }
270
+ };
271
+ export const resolveBrandingAssetCookieOptions = (headers) => {
272
+ const host = resolveRequestHost(headers);
273
+ const protocol = headers.get('x-forwarded-proto') ?? 'https';
274
+ const isTreasury = /(?:^|\.)treasury\.space$/.test(host);
275
+ return {
276
+ name: readEnv(process.env.ASSETS_COOKIE_NAME) || 'treasury_assets_token',
277
+ domain: isTreasury ? '.treasury.space' : undefined,
278
+ sameSite: isTreasury ? 'none' : 'lax',
279
+ secure: isTreasury ? true : protocol === 'https',
280
+ };
281
+ };
282
+ export const buildBrandingAssetCookie = async ({ headers, logoUrl, requestAssetToken, assetScope = DEFAULT_BRANDING_SCOPE, assetPrefix = DEFAULT_BRANDING_PREFIX, assetTtl = DEFAULT_BRANDING_TTL, assetAudience = DEFAULT_BRANDING_AUDIENCE, }) => {
283
+ if (!shouldSignSurfaceBrandingAsset(logoUrl)) {
284
+ return null;
285
+ }
286
+ const token = await requestAssetToken({
287
+ scope: assetScope,
288
+ prefix: assetPrefix,
289
+ ttl: assetTtl,
290
+ audience: assetAudience,
291
+ });
292
+ const cookie = resolveBrandingAssetCookieOptions(headers);
293
+ return {
294
+ ...cookie,
295
+ value: token.token,
296
+ maxAge: token.expiresIn ?? assetTtl,
297
+ path: '/',
298
+ };
299
+ };
300
+ export const buildSurfaceBrandingAssetCookie = async ({ headers, surfaceContext, requestAssetToken, assetScope = DEFAULT_BRANDING_SCOPE, assetPrefix = DEFAULT_BRANDING_PREFIX, assetTtl = DEFAULT_BRANDING_TTL, assetAudience = DEFAULT_BRANDING_AUDIENCE, ...fetchOptions }) => {
301
+ const brandingPayload = await fetchSurfaceBranding(surfaceContext, fetchOptions);
302
+ const branding = normalizeSurfaceBrandingPayload(brandingPayload);
303
+ return buildBrandingAssetCookie({
304
+ headers,
305
+ logoUrl: branding?.logoUrl ?? null,
306
+ requestAssetToken,
307
+ assetScope,
308
+ assetPrefix,
309
+ assetTtl,
310
+ assetAudience,
311
+ });
312
+ };
313
+ export const bootstrapSurfaceBranding = async ({ headers, surfaceContext, manifest = null, brandingPayload, requestAssetToken, assetScope, assetPrefix, assetTtl, assetAudience, ...fetchOptions }) => {
314
+ const brandingSource = brandingPayload ?? (await fetchSurfaceBranding(surfaceContext, fetchOptions));
315
+ const branding = normalizeSurfaceBrandingPayload(brandingSource);
316
+ const brandedManifest = manifest ? applySurfaceBrandingToManifest(manifest, branding) : null;
317
+ const assetCookie = requestAssetToken && branding?.logoUrl
318
+ ? await buildBrandingAssetCookie({
319
+ headers,
320
+ logoUrl: branding.logoUrl,
321
+ requestAssetToken,
322
+ assetScope,
323
+ assetPrefix,
324
+ assetTtl,
325
+ assetAudience,
326
+ })
327
+ : null;
328
+ return {
329
+ branding,
330
+ manifest: brandedManifest,
331
+ assetCookie,
332
+ };
333
+ };
334
+ export const isSurfaceStaticBypassPath = (pathname, extraPrefixes = []) => {
335
+ if (DEFAULT_BYPASS_EXACT.has(pathname))
336
+ return true;
337
+ if ([...DEFAULT_BYPASS_PREFIXES, ...extraPrefixes].some((prefix) => pathname.startsWith(prefix)))
338
+ return true;
339
+ return DEFAULT_BYPASS_PATTERN.test(pathname);
340
+ };
341
+ export const createSurfaceMiddleware = ({ resolveSurfaceHostContext, requestAssetToken, bypass, allowUnauthenticated, attachBrandingCookie, loginPath = '/login', clearCookieNames = [], redirectAuthenticatedFromLogin, redirectUnauthenticated, redirectUnauthorized, onAuthorized, ...fetchOptions }) => {
342
+ const defaultRedirectToLogin = (request) => {
343
+ const redirectUrl = request.nextUrl.clone();
344
+ redirectUrl.pathname = loginPath;
345
+ redirectUrl.search = `?from=${encodeURIComponent(`${request.nextUrl.pathname}${request.nextUrl.search}`)}`;
346
+ return redirectUrl;
347
+ };
348
+ const maybeAttachBrandingCookie = async (request, response, surfaceContext) => {
349
+ const shouldAttach = attachBrandingCookie ? attachBrandingCookie(request.nextUrl.pathname, surfaceContext) : false;
350
+ if (!shouldAttach || !requestAssetToken) {
351
+ return response;
352
+ }
353
+ try {
354
+ const { assetCookie } = await bootstrapSurfaceBranding({
355
+ headers: request.headers,
356
+ surfaceContext,
357
+ requestAssetToken,
358
+ ...fetchOptions,
359
+ });
360
+ if (assetCookie) {
361
+ response.cookies.set(assetCookie.name, assetCookie.value, {
362
+ httpOnly: false,
363
+ secure: assetCookie.secure,
364
+ sameSite: assetCookie.sameSite,
365
+ domain: assetCookie.domain,
366
+ path: assetCookie.path,
367
+ maxAge: assetCookie.maxAge,
368
+ });
369
+ }
370
+ }
371
+ catch {
372
+ // Branding bootstrap is best-effort; page delivery should not fail.
373
+ }
374
+ return response;
375
+ };
376
+ const clearCookies = (response) => {
377
+ clearSurfaceAuthCookie(response.cookies);
378
+ clearCookieNames.forEach((name) => response.cookies.set(name, '', { path: '/', maxAge: 0 }));
379
+ return response;
380
+ };
381
+ return async (request) => {
382
+ const { pathname } = request.nextUrl;
383
+ const { surfaceContext } = resolveSurfaceRequestContext(request, resolveSurfaceHostContext);
384
+ if (isSurfaceStaticBypassPath(pathname) || bypass?.(pathname, surfaceContext) || pathname.startsWith('/api/')) {
385
+ return NextResponse.next();
386
+ }
387
+ const token = readSurfaceAuthToken(request.cookies);
388
+ if (pathname === loginPath) {
389
+ if (!token) {
390
+ return maybeAttachBrandingCookie(request, NextResponse.next(), surfaceContext);
391
+ }
392
+ const validation = await validateSurfaceBrowserSession({
393
+ token,
394
+ surfaceContext,
395
+ ...fetchOptions,
396
+ });
397
+ if (validation.valid) {
398
+ return NextResponse.redirect(redirectAuthenticatedFromLogin?.(request, surfaceContext) ?? new URL('/', request.url));
399
+ }
400
+ return maybeAttachBrandingCookie(request, clearCookies(NextResponse.next()), surfaceContext);
401
+ }
402
+ const isPublic = allowUnauthenticated?.(pathname, surfaceContext) ?? false;
403
+ if (!token) {
404
+ if (isPublic) {
405
+ return maybeAttachBrandingCookie(request, NextResponse.next(), surfaceContext);
406
+ }
407
+ return NextResponse.redirect(redirectUnauthenticated?.(request, surfaceContext) ?? defaultRedirectToLogin(request));
408
+ }
409
+ const validation = await validateSurfaceBrowserSession({
410
+ token,
411
+ surfaceContext,
412
+ ...fetchOptions,
413
+ });
414
+ if (!validation.valid) {
415
+ if (isPublic) {
416
+ return maybeAttachBrandingCookie(request, clearCookies(NextResponse.next()), surfaceContext);
417
+ }
418
+ return clearCookies(NextResponse.redirect(redirectUnauthorized?.(request, surfaceContext) ?? defaultRedirectToLogin(request)));
419
+ }
420
+ const authorizedResponse = await onAuthorized?.(request, validation, surfaceContext);
421
+ if (authorizedResponse) {
422
+ return authorizedResponse;
423
+ }
424
+ return maybeAttachBrandingCookie(request, NextResponse.next(), surfaceContext);
425
+ };
426
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treasuryspatial/surface-kit",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,10 @@
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
11
  "default": "./dist/index.js"
12
+ },
13
+ "./server": {
14
+ "types": "./dist/server.d.ts",
15
+ "default": "./dist/server.js"
12
16
  }
13
17
  },
14
18
  "files": [
@@ -21,6 +25,9 @@
21
25
  "@treasuryspatial/mode-policy": "^0.1.5",
22
26
  "@treasuryspatial/ui-manifest": "^0.1.7"
23
27
  },
28
+ "peerDependencies": {
29
+ "next": "^15.0.0 || ^16.0.0"
30
+ },
24
31
  "scripts": {
25
32
  "build": "tsc -b",
26
33
  "test": "npm run build && node --test test/*.test.mjs",