@geekapps/auth-nextjs 0.1.0 → 0.1.2

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.
@@ -0,0 +1,15 @@
1
+ import { ConnectedAccount, User, Organization } from './client.js';
2
+ import 'react';
3
+
4
+ declare function getMe(): Promise<{
5
+ user: User | null;
6
+ }>;
7
+ declare function getAccounts(): Promise<{
8
+ accounts: ConnectedAccount[];
9
+ }>;
10
+ declare function getOrganizations(): Promise<{
11
+ organizations: Organization[];
12
+ currentOrgId?: string | null;
13
+ }>;
14
+
15
+ export { getAccounts, getMe, getOrganizations };
@@ -0,0 +1,203 @@
1
+ "use server";
2
+
3
+ // src/actions.ts
4
+ import { cookies } from "next/headers";
5
+ function env(name) {
6
+ const value = process.env[name];
7
+ return value && value.trim().length > 0 ? value : void 0;
8
+ }
9
+ function normalizeBaseUrl(url) {
10
+ return url.replace(/\/$/, "");
11
+ }
12
+ function resolveIssuer() {
13
+ return normalizeBaseUrl(
14
+ env("GEEKAPPS_AUTH_ISSUER") ?? env("GEEKAPPS_AUTH_API_URL") ?? "http://localhost:3020"
15
+ );
16
+ }
17
+ function getServerClientHeaders() {
18
+ const clientId = env("GEEKAPPS_AUTH_CLIENT_ID");
19
+ const clientSecret = env("GEEKAPPS_AUTH_CLIENT_SECRET");
20
+ return clientId && clientSecret ? {
21
+ "x-geekapps-client-id": clientId,
22
+ "x-geekapps-client-secret": clientSecret
23
+ } : {};
24
+ }
25
+ function hashClientId(clientId) {
26
+ let h = 5381;
27
+ for (let i = 0; i < clientId.length; i++) {
28
+ h = (h << 5) + h ^ clientId.charCodeAt(i) & 255;
29
+ h = h >>> 0;
30
+ }
31
+ return h.toString(16).padStart(8, "0");
32
+ }
33
+ function deriveCookiePrefix() {
34
+ const clientId = env("GEEKAPPS_AUTH_CLIENT_ID") ?? "";
35
+ if (!clientId) return "gk";
36
+ return `gk_${hashClientId(clientId)}`;
37
+ }
38
+ function decodeMeta(value) {
39
+ try {
40
+ const m = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
41
+ return m.id ? m : null;
42
+ } catch {
43
+ return null;
44
+ }
45
+ }
46
+ async function getCookieNames() {
47
+ const prefix = deriveCookiePrefix();
48
+ return {
49
+ active: `${prefix}_active`,
50
+ count: `${prefix}_count`,
51
+ activeOrganizationId: `${prefix}_ao`,
52
+ slotMeta: (n) => `${prefix}_m${n}`,
53
+ slotAt: (n) => `${prefix}_at${n}`,
54
+ slotRt: (n) => `${prefix}_rt${n}`
55
+ };
56
+ }
57
+ async function getActiveAccessToken() {
58
+ const cookieStore = await cookies();
59
+ const cn = await getCookieNames();
60
+ const raw = cookieStore.get(cn.active)?.value;
61
+ const activeIdx = raw ? Number.parseInt(raw, 10) : 0;
62
+ const countRaw = cookieStore.get(cn.count)?.value;
63
+ const count = countRaw ? Number.parseInt(countRaw, 10) : 0;
64
+ if (count === 0) return null;
65
+ const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;
66
+ return cookieStore.get(cn.slotAt(idx))?.value ?? null;
67
+ }
68
+ async function getActiveRefreshToken() {
69
+ const cookieStore = await cookies();
70
+ const cn = await getCookieNames();
71
+ const raw = cookieStore.get(cn.active)?.value;
72
+ const activeIdx = raw ? Number.parseInt(raw, 10) : 0;
73
+ const countRaw = cookieStore.get(cn.count)?.value;
74
+ const count = countRaw ? Number.parseInt(countRaw, 10) : 0;
75
+ if (count === 0) return null;
76
+ const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;
77
+ return cookieStore.get(cn.slotRt(idx))?.value ?? null;
78
+ }
79
+ async function refreshAndSaveTokens() {
80
+ const refreshToken = await getActiveRefreshToken();
81
+ const clientId = env("GEEKAPPS_AUTH_CLIENT_ID") ?? "";
82
+ const clientSecret = env("GEEKAPPS_AUTH_CLIENT_SECRET") ?? "";
83
+ if (!refreshToken || !clientId) return null;
84
+ const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString("base64");
85
+ const response = await fetch(`${resolveIssuer()}/auth/refresh`, {
86
+ method: "POST",
87
+ headers: {
88
+ "content-type": "application/x-www-form-urlencoded",
89
+ authorization: `Basic ${basicAuth}`
90
+ },
91
+ body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken }),
92
+ cache: "no-store"
93
+ });
94
+ if (!response.ok) return null;
95
+ const data = await response.json().catch(() => null);
96
+ if (!data) return null;
97
+ const newAccessToken = data.accessToken ?? data.access_token;
98
+ const newRefreshToken = data.refreshToken ?? data.refresh_token;
99
+ if (!newAccessToken) return null;
100
+ const cookieStore = await cookies();
101
+ const cn = await getCookieNames();
102
+ const raw = cookieStore.get(cn.active)?.value;
103
+ const activeIdx = raw ? Number.parseInt(raw, 10) : 1;
104
+ const opts = {
105
+ httpOnly: true,
106
+ secure: process.env.NODE_ENV === "production",
107
+ sameSite: "lax",
108
+ path: "/",
109
+ maxAge: 60 * 60 * 24 * 30
110
+ };
111
+ cookieStore.set(cn.slotAt(activeIdx), newAccessToken, opts);
112
+ if (newRefreshToken) cookieStore.set(cn.slotRt(activeIdx), newRefreshToken, opts);
113
+ cookieStore.set(`${deriveCookiePrefix()}_tp`, newAccessToken, {
114
+ httpOnly: false,
115
+ secure: process.env.NODE_ENV === "production",
116
+ sameSite: "lax",
117
+ path: "/",
118
+ maxAge: 60 * 60 * 24 * 30
119
+ });
120
+ return newAccessToken;
121
+ }
122
+ async function authFetch(path) {
123
+ let accessToken = await getActiveAccessToken();
124
+ if (!accessToken) throw new Error("Not authenticated");
125
+ const issuer = resolveIssuer();
126
+ const doFetch = (token) => fetch(`${issuer}${path}`, {
127
+ headers: {
128
+ authorization: `Bearer ${token}`,
129
+ ...getServerClientHeaders()
130
+ },
131
+ cache: "no-store"
132
+ });
133
+ let response = await doFetch(accessToken);
134
+ if (response.status === 401) {
135
+ const newToken = await refreshAndSaveTokens();
136
+ if (!newToken) throw new Error("Session expired");
137
+ response = await doFetch(newToken);
138
+ }
139
+ if (!response.ok) {
140
+ const err = await response.json().catch(() => null);
141
+ throw new Error(err?.error_description ?? err?.error ?? err?.message ?? `Auth error ${response.status}`);
142
+ }
143
+ if (response.status === 204) return null;
144
+ return response.json();
145
+ }
146
+ async function getMe() {
147
+ try {
148
+ const data = await authFetch("/auth/me");
149
+ if (!data) return { user: null };
150
+ if (typeof data === "object" && "user" in data) return data;
151
+ return { user: data };
152
+ } catch {
153
+ return { user: null };
154
+ }
155
+ }
156
+ async function getAccounts() {
157
+ const cookieStore = await cookies();
158
+ const cn = await getCookieNames();
159
+ const countRaw = cookieStore.get(cn.count)?.value;
160
+ const count = countRaw ? Number.parseInt(countRaw, 10) : 0;
161
+ const activeRaw = cookieStore.get(cn.active)?.value;
162
+ const activeIdx = activeRaw ? Number.parseInt(activeRaw, 10) : 0;
163
+ const accounts = [];
164
+ for (let i = 1; i <= count; i++) {
165
+ const at = cookieStore.get(cn.slotAt(i))?.value;
166
+ if (!at) continue;
167
+ const meta = decodeMeta(cookieStore.get(cn.slotMeta(i))?.value ?? "");
168
+ if (!meta) continue;
169
+ accounts.push({
170
+ id: meta.id,
171
+ sessionId: meta.sid ?? meta.id,
172
+ isActive: i === activeIdx,
173
+ user: {
174
+ id: meta.id,
175
+ name: meta.n ?? null,
176
+ email: meta.e ?? "",
177
+ imageUrl: meta.p ?? null,
178
+ phone: null
179
+ }
180
+ });
181
+ }
182
+ return { accounts };
183
+ }
184
+ async function getOrganizations() {
185
+ try {
186
+ const cookieStore = await cookies();
187
+ const cn = await getCookieNames();
188
+ const activeOrgId = cookieStore.get(cn.activeOrganizationId)?.value ?? null;
189
+ const data = await authFetch("/organizations");
190
+ const organizations = Array.isArray(data) ? data : data.organizations;
191
+ const resolvedOrgId = activeOrgId ?? organizations[0]?.id ?? null;
192
+ return { organizations, currentOrgId: resolvedOrgId };
193
+ } catch (err) {
194
+ console.error("[getOrganizations] error:", err);
195
+ return { organizations: [] };
196
+ }
197
+ }
198
+ export {
199
+ getAccounts,
200
+ getMe,
201
+ getOrganizations
202
+ };
203
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/actions.ts"],"sourcesContent":["\"use server\";\n\nimport { cookies } from \"next/headers\";\nimport type { ConnectedAccount, Organization, User } from \"./client\";\n\n// ── cookie helpers (duplicated from server.ts to keep this file self-contained) ──\n\nfunction env(name: string) {\n const value = process.env[name];\n return value && value.trim().length > 0 ? value : undefined;\n}\n\nfunction normalizeBaseUrl(url: string) {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction resolveIssuer() {\n return normalizeBaseUrl(\n env(\"GEEKAPPS_AUTH_ISSUER\") ?? env(\"GEEKAPPS_AUTH_API_URL\") ?? \"http://localhost:3020\",\n );\n}\n\nfunction getServerClientHeaders() {\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\");\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\");\n\n return clientId && clientSecret\n ? {\n \"x-geekapps-client-id\": clientId,\n \"x-geekapps-client-secret\": clientSecret,\n }\n : {};\n}\n\nfunction hashClientId(clientId: string): string {\n let h = 5381;\n for (let i = 0; i < clientId.length; i++) {\n h = ((h << 5) + h) ^ (clientId.charCodeAt(i) & 0xff);\n h = h >>> 0;\n }\n return h.toString(16).padStart(8, \"0\");\n}\n\nfunction deriveCookiePrefix(): string {\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\") ?? \"\";\n if (!clientId) return \"gk\";\n return `gk_${hashClientId(clientId)}`;\n}\n\ntype SlotMeta = { id: string; sid?: string; n?: string; e?: string; p?: string };\n\nfunction decodeMeta(value: string): SlotMeta | null {\n try {\n const m = JSON.parse(Buffer.from(value, \"base64url\").toString(\"utf8\")) as SlotMeta;\n return m.id ? m : null;\n } catch {\n return null;\n }\n}\n\nasync function getCookieNames() {\n const prefix = deriveCookiePrefix();\n return {\n active: `${prefix}_active`,\n count: `${prefix}_count`,\n activeOrganizationId: `${prefix}_ao`,\n slotMeta: (n: number) => `${prefix}_m${n}`,\n slotAt: (n: number) => `${prefix}_at${n}`,\n slotRt: (n: number) => `${prefix}_rt${n}`,\n };\n}\n\nasync function getActiveAccessToken(): Promise<string | null> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 0;\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n if (count === 0) return null;\n const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;\n return cookieStore.get(cn.slotAt(idx))?.value ?? null;\n}\n\nasync function getActiveRefreshToken(): Promise<string | null> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 0;\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n if (count === 0) return null;\n const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;\n return cookieStore.get(cn.slotRt(idx))?.value ?? null;\n}\n\nasync function refreshAndSaveTokens(): Promise<string | null> {\n const refreshToken = await getActiveRefreshToken();\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\") ?? \"\";\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\") ?? \"\";\n if (!refreshToken || !clientId) return null;\n\n const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString(\"base64\");\n const response = await fetch(`${resolveIssuer()}/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/x-www-form-urlencoded\",\n authorization: `Basic ${basicAuth}`,\n },\n body: new URLSearchParams({ grant_type: \"refresh_token\", refresh_token: refreshToken }),\n cache: \"no-store\",\n });\n\n if (!response.ok) return null;\n\n const data = await response.json().catch(() => null) as Record<string, unknown> | null;\n if (!data) return null;\n\n const newAccessToken =\n (data.accessToken ?? data.access_token) as string | undefined;\n const newRefreshToken =\n (data.refreshToken ?? data.refresh_token) as string | undefined;\n\n if (!newAccessToken) return null;\n\n // Update the active slot cookies\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 1;\n const opts = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n };\n cookieStore.set(cn.slotAt(activeIdx), newAccessToken, opts);\n if (newRefreshToken) cookieStore.set(cn.slotRt(activeIdx), newRefreshToken, opts);\n // Update public token cookie\n cookieStore.set(`${deriveCookiePrefix()}_tp`, newAccessToken, {\n httpOnly: false,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\",\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n });\n\n return newAccessToken;\n}\n\nasync function authFetch<T>(path: string): Promise<T> {\n let accessToken = await getActiveAccessToken();\n if (!accessToken) throw new Error(\"Not authenticated\");\n\n const issuer = resolveIssuer();\n const doFetch = (token: string) =>\n fetch(`${issuer}${path}`, {\n headers: {\n authorization: `Bearer ${token}`,\n ...getServerClientHeaders(),\n } as HeadersInit,\n cache: \"no-store\",\n });\n\n let response = await doFetch(accessToken);\n\n if (response.status === 401) {\n const newToken = await refreshAndSaveTokens();\n if (!newToken) throw new Error(\"Session expired\");\n response = await doFetch(newToken);\n }\n\n if (!response.ok) {\n const err = await response.json().catch(() => null) as Record<string, unknown> | null;\n throw new Error((err?.error_description ?? err?.error ?? err?.message ?? `Auth error ${response.status}`) as string);\n }\n\n if (response.status === 204) return null as T;\n return response.json() as Promise<T>;\n}\n\n// ── Exported server actions ────────────────────────────────────────────────────\n\nexport async function getMe(): Promise<{ user: User | null }> {\n try {\n const data = await authFetch<{ user: User | null } | User | null>(\"/auth/me\");\n if (!data) return { user: null };\n if (typeof data === \"object\" && \"user\" in data) return data as { user: User | null };\n return { user: data as User | null };\n } catch {\n return { user: null };\n }\n}\n\nexport async function getAccounts(): Promise<{ accounts: ConnectedAccount[] }> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n const activeRaw = cookieStore.get(cn.active)?.value;\n const activeIdx = activeRaw ? Number.parseInt(activeRaw, 10) : 0;\n\n const accounts: ConnectedAccount[] = [];\n for (let i = 1; i <= count; i++) {\n const at = cookieStore.get(cn.slotAt(i))?.value;\n if (!at) continue;\n const meta = decodeMeta(cookieStore.get(cn.slotMeta(i))?.value ?? \"\");\n if (!meta) continue;\n accounts.push({\n id: meta.id,\n sessionId: meta.sid ?? meta.id,\n isActive: i === activeIdx,\n user: {\n id: meta.id,\n name: meta.n ?? null,\n email: meta.e ?? \"\",\n imageUrl: meta.p ?? null,\n phone: null,\n },\n });\n }\n\n return { accounts };\n}\n\nexport async function getOrganizations(): Promise<{ organizations: Organization[]; currentOrgId?: string | null }> {\n try {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const activeOrgId = cookieStore.get(cn.activeOrganizationId)?.value ?? null;\n const data = await authFetch<Organization[] | { organizations: Organization[] }>(\"/organizations\");\n const organizations = Array.isArray(data) ? data : (data as { organizations: Organization[] }).organizations;\n const resolvedOrgId = activeOrgId ?? organizations[0]?.id ?? null;\n return { organizations, currentOrgId: resolvedOrgId };\n } catch (err) {\n console.error(\"[getOrganizations] error:\", err);\n return { organizations: [] };\n }\n}\n"],"mappings":"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","names":[]}
package/dist/client.js CHANGED
@@ -183,7 +183,7 @@ async function getAccounts() {
183
183
  user: {
184
184
  id: meta.id,
185
185
  name: meta.n ?? null,
186
- email: meta.e ?? null,
186
+ email: meta.e ?? "",
187
187
  imageUrl: meta.p ?? null,
188
188
  phone: null
189
189
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.tsx","../src/actions.ts"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { getMe, getAccounts, getOrganizations } from \"./actions\";\n\nexport type UserStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OrganizationStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OAuthClientType = \"public\" | \"confidential\";\n\nexport type AuthResult<T = unknown> =\n | { success: true; data: T }\n | { success: false; error: string; status?: number };\n\nexport type User = {\n id: string;\n email: string;\n name: string | null;\n phone: string | null;\n imageUrl: string | null;\n status?: UserStatus;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type ConnectedAccount = {\n id: string;\n sessionId?: string;\n isActive: boolean;\n user: User;\n};\n\nexport type Permission = {\n id: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description: string | null;\n category: string | null;\n isSystem: boolean;\n isActive: boolean;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RolePermission = {\n permissionDefinition: Permission;\n};\n\nexport type Role = {\n id: string;\n applicationId?: string | null;\n /** Present only on custom roles */\n organizationId?: string | null;\n /** \"system\" | \"custom\" */\n type?: string;\n key: string;\n name: string;\n description: string | null;\n isSystem?: boolean;\n isDefault?: boolean;\n isActive: boolean;\n permissions: RolePermission[];\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RoleAssignment = {\n id: string;\n roleDefinitionId?: string | null;\n customRoleId?: string | null;\n roleDefinition?: Role | null;\n customRole?: Role | null;\n};\n\nexport type OrganizationMember = {\n id: string;\n organizationId?: string;\n userId?: string;\n createdAt?: string | Date;\n user: User;\n roleAssignments?: RoleAssignment[];\n};\n\nexport type OrganizationOwnedApplication = {\n id: string;\n name: string;\n description: string | null;\n imageUrl: string | null;\n type?: OAuthClientType;\n organizationId: string;\n isFirstParty: boolean;\n ssoEnabled: boolean;\n status?: \"active\" | \"inactive\" | \"suspended\";\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type Organization = {\n id: string;\n name: string;\n description: string | null;\n slug: string;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n status: OrganizationStatus;\n members?: OrganizationMember[];\n ownedApplications?: OrganizationOwnedApplication[];\n applicationLinks?: Array<{\n id: string;\n status: OrganizationStatus;\n createdAt?: string | Date;\n application: OrganizationOwnedApplication;\n }>;\n createdAt: string | Date;\n updatedAt: string | Date;\n};\n\nexport type SessionApplication = {\n id: string;\n createdAt: string | Date;\n expiresAt: string | Date;\n application: {\n id: string;\n name: string;\n organizationId: string;\n };\n};\n\nexport type UserSession = {\n id: string;\n userId: string;\n organizationId: string | null;\n deviceAgent: string | null;\n deviceId: string | null;\n deviceName: string | null;\n ip: string | null;\n authState?: unknown;\n authTime?: string | Date;\n expiresAt: string | Date;\n createdAt: string | Date;\n updatedAt: string | Date;\n user?: User;\n applicationSessions?: SessionApplication[];\n};\n\nexport type UserInput = {\n name?: string | null;\n email?: string;\n phone?: string | null;\n imageUrl?: string | null;\n password?: string;\n organizationId?: string | null;\n status?: UserStatus;\n};\n\nexport type OrganizationInput = {\n name: string;\n description?: string | null;\n slug: string;\n domain?: string | null;\n imageUrl?: string | null;\n faviconUrl?: string | null;\n};\n\nexport type OrganizationUpdateInput = Partial<OrganizationInput> & {\n status?: OrganizationStatus;\n};\n\nexport type RoleInput = {\n organizationId: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n permissionDefinitionIds?: string[];\n};\n\nexport type RoleUpdateInput = {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n permissionDefinitionIds?: string[];\n};\n\nexport type PermissionInput = {\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n category?: string | null;\n};\n\nexport type PermissionUpdateInput = {\n name?: string;\n description?: string | null;\n category?: string | null;\n isActive?: boolean;\n};\n\nexport type SignInOptions = {\n redirectTo?: string;\n authorizationFlowId?: string;\n};\n\nexport type SignInInput = SignInOptions | MouseEvent<HTMLElement>;\n\nexport type CallbackUrlOptions = SignInOptions & {\n callbackUrl?: string;\n};\n\nexport type PermissionCheckOptions = {\n permission: string;\n organizationId?: string | null;\n applicationId?: string | null;\n resourceId?: string | null;\n};\n\nexport type LoginResponse = {\n user: User;\n redirectTo?: string | null;\n};\n\nexport type RegisterResponse = User;\n\nexport type GeekappsAuthProviderProps = {\n children: ReactNode;\n basePath?: string;\n initialUser?: User | null;\n initialOrganizations?: Organization[];\n initialCurrentOrgId?: string | null;\n};\n\ntype RequestOptions = {\n body?: unknown;\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n};\n\nfunction normalizeBasePath(basePath: string) {\n return basePath.endsWith(\"/\") ? basePath.slice(0, -1) : basePath;\n}\n\nfunction buildUrl(basePath: string, path: string) {\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${normalizeBasePath(basePath)}${normalizedPath}`;\n}\n\nasync function parseError(response: Response) {\n const data = await response.json().catch(() => null);\n return (\n data?.error_description ??\n data?.error ??\n data?.message ??\n `Request failed with status ${response.status}`\n );\n}\n\nfunction redirectTo(path: string) {\n window.location.assign(path);\n}\n\nfunction isMouseEvent(value: unknown): value is MouseEvent<HTMLElement> {\n return Boolean(value && typeof value === \"object\" && \"preventDefault\" in value);\n}\n\nfunction normalizeSignInOptions(input?: SignInInput): SignInOptions | undefined {\n if (!input) return undefined;\n if (isMouseEvent(input)) {\n input.preventDefault();\n return undefined;\n }\n return input;\n}\n\n\ntype ClientActionOptions = {\n basePath?: string;\n};\n\nasync function clientRequest<T>(\n path: string,\n options: RequestOptions = {},\n basePath = \"/api/auth\",\n): Promise<T> {\n const response = await fetch(buildUrl(basePath, path), {\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n method: options.method ?? \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(await parseError(response));\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n}\n\nasync function toStandaloneAuthResult<T>(\n fn: () => Promise<T>,\n): Promise<AuthResult<T>> {\n try {\n return {\n success: true,\n data: await fn(),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Auth request failed\",\n };\n }\n}\n\nexport async function loginWithPassword(\n params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<LoginResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<LoginResponse>(\n \"/login/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo ?? data.redirectTo) {\n redirectTo(params.redirectTo ?? data.redirectTo!);\n }\n\n return data;\n });\n}\n\nexport async function registerWithPassword(\n params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<RegisterResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<RegisterResponse>(\n \"/register/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo) {\n redirectTo(params.redirectTo);\n }\n\n return data;\n });\n}\n\nexport function startGoogleLogin(\n params?: CallbackUrlOptions,\n options?: ClientActionOptions,\n) {\n const basePath = options?.basePath ?? \"/api/auth\";\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n\n if (params?.callbackUrl) {\n url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n }\n\n if (params?.redirectTo) {\n url.searchParams.set(\"redirectTo\", params.redirectTo);\n }\n\n if (params?.authorizationFlowId) {\n url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n }\n\n redirectTo(url.toString());\n}\n\nexport async function requestPasswordlessLink(\n params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult> {\n return toStandaloneAuthResult(() =>\n clientRequest(\n \"/passwordless/link\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n ),\n );\n}\n\nexport type GeekappsAuthContextValue = {\n basePath: string;\n user: User | null;\n isLoading: boolean;\n accounts: ConnectedAccount[];\n isLoadingAccounts: boolean;\n organizations: Organization[];\n currentOrg: Organization | null;\n currentOrgId: string | null;\n isLoadingOrganizations: boolean;\n\n request: <T>(path: string, options?: RequestOptions) => Promise<T>;\n\n signIn: (options?: SignInInput) => Promise<void>;\n signUp: (options?: SignInInput) => Promise<void>;\n addAccount: (options?: SignInInput) => Promise<void>;\n signOut: () => Promise<void>;\n signOutAll: () => Promise<void>;\n refreshUser: () => Promise<void>;\n refreshAccounts: () => Promise<void>;\n switchAccount: (sessionId: string, options?: SignInOptions) => Promise<void>;\n\n loginWithPassword: (params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n }) => Promise<AuthResult<LoginResponse>>;\n registerWithPassword: (params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n }) => Promise<AuthResult<RegisterResponse>>;\n startGoogleLogin: (params?: CallbackUrlOptions) => void;\n requestPasswordlessLink: (params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n }) => Promise<AuthResult>;\n\n refreshOrganizations: () => Promise<void>;\n setCurrentOrg: (organizationId: string | null) => Promise<void>;\n createOrganization: (input: OrganizationInput) => Promise<AuthResult<Organization>>;\n updateOrganization: (id: string, input: OrganizationUpdateInput) => Promise<AuthResult<Organization>>;\n deleteOrganization: (id: string) => Promise<AuthResult<null>>;\n hasPermission: (options: PermissionCheckOptions) => Promise<boolean>;\n\n listUsers: (params?: { organizationId?: string | null }) => Promise<User[]>;\n getUser: (id: string) => Promise<User>;\n createUser: (input: UserInput) => Promise<AuthResult<User>>;\n updateUser: (id: string, input: UserInput) => Promise<AuthResult<User>>;\n deleteUser: (id: string) => Promise<AuthResult<null>>;\n\n listRoles: (params: { organizationId?: string; applicationId?: string; type?: \"system\" | \"custom\" | \"all\" }) => Promise<{ systemRoles: Role[]; customRoles: Role[] }>;\n getRole: (id: string, type: \"system\" | \"custom\") => Promise<Role>;\n createRole: (input: RoleInput) => Promise<AuthResult<Role>>;\n updateRole: (id: string, input: RoleUpdateInput) => Promise<AuthResult<Role>>;\n deleteRole: (id: string) => Promise<AuthResult<null>>;\n\n listPermissions: (params: { applicationId?: string; roleId?: string | null }) => Promise<Permission[]>;\n createPermission: (input: PermissionInput) => Promise<AuthResult<Permission>>;\n updatePermission: (id: string, input: PermissionUpdateInput) => Promise<AuthResult<Permission>>;\n deletePermission: (id: string) => Promise<AuthResult<null>>;\n\n listUserSessions: (params?: { userId?: string; organizationId?: string | null }) => Promise<UserSession[]>;\n revokeUserSession: (sessionId: string) => Promise<AuthResult<null>>;\n};\n\nexport type UseOrgResult = Pick<\n GeekappsAuthContextValue,\n | \"organizations\"\n | \"currentOrg\"\n | \"currentOrgId\"\n | \"isLoadingOrganizations\"\n | \"refreshOrganizations\"\n | \"setCurrentOrg\"\n | \"createOrganization\"\n | \"updateOrganization\"\n | \"deleteOrganization\"\n | \"hasPermission\"\n>;\n\nexport type UseAccountsResult = Pick<\n GeekappsAuthContextValue,\n \"accounts\" | \"addAccount\" | \"isLoadingAccounts\" | \"refreshAccounts\" | \"switchAccount\"\n>;\n\nexport type UseUsersResult = Pick<\n GeekappsAuthContextValue,\n \"listUsers\" | \"getUser\" | \"createUser\" | \"updateUser\" | \"deleteUser\"\n>;\n\nexport type UseRolesResult = Pick<\n GeekappsAuthContextValue,\n \"listRoles\" | \"getRole\" | \"createRole\" | \"updateRole\" | \"deleteRole\"\n>;\n\nexport type UsePermissionsResult = Pick<\n GeekappsAuthContextValue,\n \"listPermissions\" | \"createPermission\" | \"updatePermission\" | \"deletePermission\"\n>;\n\nexport type UseSessionsResult = Pick<\n GeekappsAuthContextValue,\n \"listUserSessions\" | \"revokeUserSession\"\n>;\n\nconst GeekappsAuthContext = createContext<GeekappsAuthContextValue | null>(null);\n\nexport function GeekappsAuthProvider({\n children,\n basePath = \"/api/auth\",\n initialUser = null,\n initialOrganizations = [],\n initialCurrentOrgId = null,\n}: GeekappsAuthProviderProps): ReactElement {\n const [user, setUser] = useState<User | null>(initialUser);\n const [isLoading, setIsLoading] = useState(true);\n const [accounts, setAccounts] = useState<ConnectedAccount[]>([]);\n const [isLoadingAccounts, setIsLoadingAccounts] = useState(true);\n const [organizations, setOrganizations] = useState<Organization[]>(initialOrganizations);\n const [currentOrgId, setCurrentOrgId] = useState<string | null>(initialCurrentOrgId);\n const [isLoadingOrganizations, setIsLoadingOrganizations] = useState(true);\n\n const request = useCallback(\n async <T,>(path: string, options: RequestOptions = {}) => {\n const response = await fetch(buildUrl(basePath, path), {\n method: options.method ?? \"GET\",\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n\n if (!response.ok) {\n throw new Error(await parseError(response));\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n },\n [basePath],\n );\n\n const refreshUser = useCallback(async () => {\n setIsLoading(true);\n try {\n const { user: u } = await getMe();\n setUser(u);\n } catch {\n setUser(null);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const refreshAccounts = useCallback(async () => {\n setIsLoadingAccounts(true);\n try {\n const { accounts: a } = await getAccounts();\n setAccounts(a);\n } catch {\n setAccounts([]);\n } finally {\n setIsLoadingAccounts(false);\n }\n }, []);\n\n const refreshOrganizations = useCallback(async () => {\n setIsLoadingOrganizations(true);\n try {\n const { organizations: orgs, currentOrgId: nextCurrentOrgId } = await getOrganizations();\n setOrganizations(orgs);\n setCurrentOrgId((current) => {\n if (nextCurrentOrgId !== undefined) return nextCurrentOrgId ?? null;\n if (current && orgs.some((org) => org.id === current)) return current;\n return orgs[0]?.id ?? null;\n });\n } catch {\n setOrganizations([]);\n setCurrentOrgId(null);\n } finally {\n setIsLoadingOrganizations(false);\n }\n }, []);\n\n useEffect(() => {\n void refreshUser();\n void refreshAccounts();\n void refreshOrganizations();\n }, [refreshAccounts, refreshOrganizations, refreshUser]);\n\n const currentOrg = useMemo(\n () => organizations.find((organization) => organization.id === currentOrgId) ?? null,\n [currentOrgId, organizations],\n );\n\n const setCurrentOrg = useCallback(\n async (organizationId: string | null) => {\n await request(\"/organizations/active\", {\n method: \"POST\",\n body: { organizationId },\n });\n setCurrentOrgId(organizationId);\n },\n [request],\n );\n\n const signIn = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-in\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signUp = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-up\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const addAccount = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/add-account\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signOut = useCallback(async () => {\n await request(\"/sign-out\", { method: \"POST\" });\n setUser(null);\n await refreshAccounts();\n }, [refreshAccounts, request]);\n\n const signOutAll = useCallback(async () => {\n await request(\"/sign-out-all\", { method: \"POST\" });\n setUser(null);\n setAccounts([]);\n }, [request]);\n\n const switchAccount = useCallback(\n async (sessionId: string, options?: SignInOptions) => {\n await request(\"/accounts/switch\", {\n method: \"POST\",\n body: { sessionId },\n });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (options?.redirectTo) redirectTo(options.redirectTo);\n },\n [refreshAccounts, refreshOrganizations, refreshUser, request],\n );\n\n async function toAuthResult<T>(fn: () => Promise<T>): Promise<AuthResult<T>> {\n try {\n return { success: true, data: await fn() };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : \"Unexpected error\" };\n }\n }\n\n const value = useMemo<GeekappsAuthContextValue>(\n () => ({\n basePath,\n user,\n isLoading,\n accounts,\n isLoadingAccounts,\n organizations,\n currentOrg,\n currentOrgId,\n isLoadingOrganizations,\n request,\n signIn,\n signUp,\n addAccount,\n signOut,\n signOutAll,\n refreshUser,\n refreshAccounts,\n switchAccount,\n loginWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<LoginResponse>(\"/login/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo ?? data.redirectTo) redirectTo(params.redirectTo ?? data.redirectTo!);\n return data;\n }),\n registerWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<RegisterResponse>(\"/register/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo) redirectTo(params.redirectTo);\n return data;\n }),\n startGoogleLogin: (params) => {\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n if (params?.callbackUrl) url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n if (params?.redirectTo) url.searchParams.set(\"redirectTo\", params.redirectTo);\n if (params?.authorizationFlowId) url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n redirectTo(url.toString());\n },\n requestPasswordlessLink: (params) =>\n toAuthResult(() => request(\"/passwordless/link\", { method: \"POST\", body: params })),\n refreshOrganizations,\n setCurrentOrg,\n createOrganization: (input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(\"/organizations\", { method: \"POST\", body: input });\n await refreshOrganizations();\n setCurrentOrgId(organization.id);\n return organization;\n }),\n updateOrganization: (id, input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(`/organizations/${id}`, { method: \"PATCH\", body: input });\n await refreshOrganizations();\n return organization;\n }),\n deleteOrganization: (id) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${id}`, { method: \"DELETE\" });\n await refreshOrganizations();\n return null;\n }),\n hasPermission: async (options) => {\n try {\n const data = await request<{ allowed: boolean }>(\"/permissions/check\", {\n method: \"POST\",\n body: options,\n });\n return data.allowed;\n } catch {\n return false;\n }\n },\n listUsers: (params) => {\n const query = new URLSearchParams();\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<User[]>(`/users${query.size ? `?${query.toString()}` : \"\"}`);\n },\n getUser: (id) => request<User>(`/users/${id}`),\n createUser: (input) => toAuthResult(() => request<User>(\"/users\", { method: \"POST\", body: input })),\n updateUser: (id, input) => toAuthResult(() => request<User>(`/users/${id}`, { method: \"PATCH\", body: input })),\n deleteUser: (id) =>\n toAuthResult(async () => {\n await request<null>(`/users/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listRoles: (params) => {\n const query = new URLSearchParams();\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n if (params?.applicationId) query.set(\"applicationId\", params.applicationId);\n if (params?.type) query.set(\"type\", params.type);\n return request<{ systemRoles: Role[]; customRoles: Role[] }>(`/roles${query.size ? `?${query.toString()}` : \"\"}`);\n },\n getRole: (id, type) => request<Role>(type === \"custom\" ? `/roles/custom/${id}` : `/roles/definitions/${id}`),\n createRole: (input) => toAuthResult(() => request<Role>(\"/roles\", { method: \"POST\", body: input })),\n updateRole: (id, input) => toAuthResult(() => request<Role>(`/roles/custom/${id}`, { method: \"PATCH\", body: input })),\n deleteRole: (id) =>\n toAuthResult(async () => {\n await request<null>(`/roles/custom/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listPermissions: (params) => {\n const query = new URLSearchParams();\n if (params?.applicationId) query.set(\"applicationId\", params.applicationId);\n if (params?.roleId) query.set(\"roleId\", params.roleId);\n return request<Permission[]>(`/permissions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n createPermission: (input) =>\n toAuthResult(() => request<Permission>(\"/permissions\", { method: \"POST\", body: input })),\n updatePermission: (id, input) =>\n toAuthResult(() => request<Permission>(`/permissions/${id}`, { method: \"PATCH\", body: input })),\n deletePermission: (id) =>\n toAuthResult(async () => {\n await request<null>(`/permissions/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listUserSessions: (params) => {\n const query = new URLSearchParams();\n if (params?.userId) query.set(\"userId\", params.userId);\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<UserSession[]>(`/sessions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n revokeUserSession: (sessionId) =>\n toAuthResult(async () => {\n await request<null>(`/sessions/${sessionId}`, { method: \"DELETE\" });\n return null;\n }),\n }),\n [\n accounts,\n addAccount,\n basePath,\n currentOrg,\n currentOrgId,\n isLoading,\n isLoadingAccounts,\n isLoadingOrganizations,\n organizations,\n refreshAccounts,\n refreshOrganizations,\n refreshUser,\n request,\n setCurrentOrg,\n signIn,\n signOut,\n signOutAll,\n signUp,\n switchAccount,\n user,\n ],\n );\n\n return <GeekappsAuthContext.Provider value={value}>{children}</GeekappsAuthContext.Provider>;\n}\n\nexport function useAuth(): GeekappsAuthContextValue {\n const context = useContext(GeekappsAuthContext);\n if (!context) throw new Error(\"useAuth must be used inside GeekappsAuthProvider\");\n return context;\n}\n\nexport function useOrg(): UseOrgResult {\n const context = useAuth();\n return {\n organizations: context.organizations,\n currentOrg: context.currentOrg,\n currentOrgId: context.currentOrgId,\n isLoadingOrganizations: context.isLoadingOrganizations,\n refreshOrganizations: context.refreshOrganizations,\n setCurrentOrg: context.setCurrentOrg,\n createOrganization: context.createOrganization,\n updateOrganization: context.updateOrganization,\n deleteOrganization: context.deleteOrganization,\n hasPermission: context.hasPermission,\n };\n}\n\nexport function useAccounts(): UseAccountsResult {\n const context = useAuth();\n return {\n accounts: context.accounts,\n addAccount: context.addAccount,\n isLoadingAccounts: context.isLoadingAccounts,\n refreshAccounts: context.refreshAccounts,\n switchAccount: context.switchAccount,\n };\n}\n\nexport function useUsers(): UseUsersResult {\n const context = useAuth();\n return {\n listUsers: context.listUsers,\n getUser: context.getUser,\n createUser: context.createUser,\n updateUser: context.updateUser,\n deleteUser: context.deleteUser,\n };\n}\n\nexport function useRoles(): UseRolesResult {\n const context = useAuth();\n return {\n listRoles: context.listRoles,\n getRole: context.getRole,\n createRole: context.createRole,\n updateRole: context.updateRole,\n deleteRole: context.deleteRole,\n };\n}\n\nexport function usePermissions(): UsePermissionsResult {\n const context = useAuth();\n return {\n listPermissions: context.listPermissions,\n createPermission: context.createPermission,\n updatePermission: context.updatePermission,\n deletePermission: context.deletePermission,\n };\n}\n\nexport function useSessions(): UseSessionsResult {\n const context = useAuth();\n return {\n listUserSessions: context.listUserSessions,\n revokeUserSession: context.revokeUserSession,\n };\n}\n\n// ── Service Accounts ─────────────────────────────────────────────────────────\n\nexport type ServiceAccount = {\n id: string;\n membershipId: string;\n organizationId: string;\n applicationId: string | null;\n name: string;\n status: \"active\" | \"inactive\" | \"suspended\";\n serviceId: string | null;\n roleAssignment: { role: { id: string; key: string; name: string } } | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type ServiceAccountWithSecret = ServiceAccount & { serviceSecret: string };\n\nexport type CreateServiceAccountInput = {\n organizationId: string;\n applicationId?: string;\n name: string;\n description?: string;\n roleId?: string;\n};\n\nexport type UseServiceAccountResult = {\n listServiceAccounts: (params: { organizationId: string; applicationId?: string }) => Promise<ServiceAccount[]>;\n createServiceAccount: (input: CreateServiceAccountInput) => Promise<ServiceAccountWithSecret>;\n updateServiceAccountRole: (id: string, roleId: string | null) => Promise<void>;\n revokeServiceAccount: (id: string) => Promise<void>;\n rotateServiceAccountSecret: (id: string) => Promise<{ serviceId: string; serviceSecret: string }>;\n deleteServiceAccount: (id: string) => Promise<void>;\n};\n\nexport function useServiceAccount(): UseServiceAccountResult {\n const { request } = useAuth();\n\n const listServiceAccounts = useCallback(\n (params: { organizationId: string; applicationId?: string }) => {\n const query = new URLSearchParams({ organizationId: params.organizationId });\n if (params.applicationId) query.set(\"applicationId\", params.applicationId);\n return request<ServiceAccount[]>(`/service-accounts?${query.toString()}`);\n },\n [request],\n );\n\n const createServiceAccount = useCallback(\n (input: CreateServiceAccountInput) =>\n request<ServiceAccountWithSecret>(\"/service-accounts\", { method: \"POST\", body: input }),\n [request],\n );\n\n const updateServiceAccountRole = useCallback(\n async (id: string, roleId: string | null) => {\n await request<void>(`/service-accounts/${id}`, { method: \"PATCH\", body: { roleId } });\n },\n [request],\n );\n\n const revokeServiceAccount = useCallback(\n async (id: string) => {\n await request<void>(`/service-accounts/${id}/revoke`, { method: \"POST\" });\n },\n [request],\n );\n\n const rotateServiceAccountSecret = useCallback(\n (id: string) =>\n request<{ serviceId: string; serviceSecret: string }>(`/service-accounts/${id}/rotate-secret`, {\n method: \"POST\",\n }),\n [request],\n );\n\n const deleteServiceAccount = useCallback(\n async (id: string) => {\n await request<null>(`/service-accounts/${id}`, { method: \"DELETE\" });\n },\n [request],\n );\n\n return {\n listServiceAccounts,\n createServiceAccount,\n updateServiceAccountRole,\n revokeServiceAccount,\n rotateServiceAccountSecret,\n deleteServiceAccount,\n };\n}\n","\"use server\";\n\nimport { cookies } from \"next/headers\";\nimport type { ConnectedAccount, Organization, User } from \"./client\";\n\n// ── cookie helpers (duplicated from server.ts to keep this file self-contained) ──\n\nfunction env(name: string) {\n const value = process.env[name];\n return value && value.trim().length > 0 ? value : undefined;\n}\n\nfunction normalizeBaseUrl(url: string) {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction resolveIssuer() {\n return normalizeBaseUrl(\n env(\"GEEKAPPS_AUTH_ISSUER\") ?? env(\"GEEKAPPS_AUTH_API_URL\") ?? \"http://localhost:3020\",\n );\n}\n\nfunction getServerClientHeaders() {\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\");\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\");\n\n return clientId && clientSecret\n ? {\n \"x-geekapps-client-id\": clientId,\n \"x-geekapps-client-secret\": clientSecret,\n }\n : {};\n}\n\nfunction hashClientId(clientId: string): string {\n let h = 5381;\n for (let i = 0; i < clientId.length; i++) {\n h = ((h << 5) + h) ^ (clientId.charCodeAt(i) & 0xff);\n h = h >>> 0;\n }\n return h.toString(16).padStart(8, \"0\");\n}\n\nfunction deriveCookiePrefix(): string {\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\") ?? \"\";\n if (!clientId) return \"gk\";\n return `gk_${hashClientId(clientId)}`;\n}\n\ntype SlotMeta = { id: string; sid?: string; n?: string; e?: string; p?: string };\n\nfunction decodeMeta(value: string): SlotMeta | null {\n try {\n const m = JSON.parse(Buffer.from(value, \"base64url\").toString(\"utf8\")) as SlotMeta;\n return m.id ? m : null;\n } catch {\n return null;\n }\n}\n\nasync function getCookieNames() {\n const prefix = deriveCookiePrefix();\n return {\n active: `${prefix}_active`,\n count: `${prefix}_count`,\n activeOrganizationId: `${prefix}_ao`,\n slotMeta: (n: number) => `${prefix}_m${n}`,\n slotAt: (n: number) => `${prefix}_at${n}`,\n slotRt: (n: number) => `${prefix}_rt${n}`,\n };\n}\n\nasync function getActiveAccessToken(): Promise<string | null> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 0;\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n if (count === 0) return null;\n const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;\n return cookieStore.get(cn.slotAt(idx))?.value ?? null;\n}\n\nasync function getActiveRefreshToken(): Promise<string | null> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 0;\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n if (count === 0) return null;\n const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;\n return cookieStore.get(cn.slotRt(idx))?.value ?? null;\n}\n\nasync function refreshAndSaveTokens(): Promise<string | null> {\n const refreshToken = await getActiveRefreshToken();\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\") ?? \"\";\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\") ?? \"\";\n if (!refreshToken || !clientId) return null;\n\n const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString(\"base64\");\n const response = await fetch(`${resolveIssuer()}/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/x-www-form-urlencoded\",\n authorization: `Basic ${basicAuth}`,\n },\n body: new URLSearchParams({ grant_type: \"refresh_token\", refresh_token: refreshToken }),\n cache: \"no-store\",\n });\n\n if (!response.ok) return null;\n\n const data = await response.json().catch(() => null) as Record<string, unknown> | null;\n if (!data) return null;\n\n const newAccessToken =\n (data.accessToken ?? data.access_token) as string | undefined;\n const newRefreshToken =\n (data.refreshToken ?? data.refresh_token) as string | undefined;\n\n if (!newAccessToken) return null;\n\n // Update the active slot cookies\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 1;\n const opts = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n };\n cookieStore.set(cn.slotAt(activeIdx), newAccessToken, opts);\n if (newRefreshToken) cookieStore.set(cn.slotRt(activeIdx), newRefreshToken, opts);\n // Update public token cookie\n cookieStore.set(`${deriveCookiePrefix()}_tp`, newAccessToken, {\n httpOnly: false,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\",\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n });\n\n return newAccessToken;\n}\n\nasync function authFetch<T>(path: string): Promise<T> {\n let accessToken = await getActiveAccessToken();\n if (!accessToken) throw new Error(\"Not authenticated\");\n\n const issuer = resolveIssuer();\n const doFetch = (token: string) =>\n fetch(`${issuer}${path}`, {\n headers: {\n authorization: `Bearer ${token}`,\n ...getServerClientHeaders(),\n },\n cache: \"no-store\",\n });\n\n let response = await doFetch(accessToken);\n\n if (response.status === 401) {\n const newToken = await refreshAndSaveTokens();\n if (!newToken) throw new Error(\"Session expired\");\n response = await doFetch(newToken);\n }\n\n if (!response.ok) {\n const err = await response.json().catch(() => null) as Record<string, unknown> | null;\n throw new Error((err?.error_description ?? err?.error ?? err?.message ?? `Auth error ${response.status}`) as string);\n }\n\n if (response.status === 204) return null as T;\n return response.json() as Promise<T>;\n}\n\n// ── Exported server actions ────────────────────────────────────────────────────\n\nexport async function getMe(): Promise<{ user: User | null }> {\n try {\n const data = await authFetch<{ user: User | null } | User | null>(\"/auth/me\");\n if (!data) return { user: null };\n if (typeof data === \"object\" && \"user\" in data) return data as { user: User | null };\n return { user: data as User | null };\n } catch {\n return { user: null };\n }\n}\n\nexport async function getAccounts(): Promise<{ accounts: ConnectedAccount[] }> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n const activeRaw = cookieStore.get(cn.active)?.value;\n const activeIdx = activeRaw ? Number.parseInt(activeRaw, 10) : 0;\n\n const accounts: ConnectedAccount[] = [];\n for (let i = 1; i <= count; i++) {\n const at = cookieStore.get(cn.slotAt(i))?.value;\n if (!at) continue;\n const meta = decodeMeta(cookieStore.get(cn.slotMeta(i))?.value ?? \"\");\n if (!meta) continue;\n accounts.push({\n id: meta.id,\n sessionId: meta.sid ?? meta.id,\n isActive: i === activeIdx,\n user: {\n id: meta.id,\n name: meta.n ?? null,\n email: meta.e ?? null,\n imageUrl: meta.p ?? null,\n phone: null,\n },\n });\n }\n\n return { accounts };\n}\n\nexport async function getOrganizations(): Promise<{ organizations: Organization[]; currentOrgId?: string | null }> {\n try {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const activeOrgId = cookieStore.get(cn.activeOrganizationId)?.value ?? null;\n const data = await authFetch<Organization[] | { organizations: Organization[] }>(\"/organizations\");\n const organizations = Array.isArray(data) ? data : (data as { organizations: Organization[] }).organizations;\n const resolvedOrgId = activeOrgId ?? organizations[0]?.id ?? null;\n return { organizations, currentOrgId: resolvedOrgId };\n } catch (err) {\n console.error(\"[getOrganizations] error:\", err);\n return { organizations: [] };\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.tsx","../src/actions.ts"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { getMe, getAccounts, getOrganizations } from \"./actions\";\n\nexport type UserStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OrganizationStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OAuthClientType = \"public\" | \"confidential\";\n\nexport type AuthResult<T = unknown> =\n | { success: true; data: T }\n | { success: false; error: string; status?: number };\n\nexport type User = {\n id: string;\n email: string;\n name: string | null;\n phone: string | null;\n imageUrl: string | null;\n status?: UserStatus;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type ConnectedAccount = {\n id: string;\n sessionId?: string;\n isActive: boolean;\n user: User;\n};\n\nexport type Permission = {\n id: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description: string | null;\n category: string | null;\n isSystem: boolean;\n isActive: boolean;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RolePermission = {\n permissionDefinition: Permission;\n};\n\nexport type Role = {\n id: string;\n applicationId?: string | null;\n /** Present only on custom roles */\n organizationId?: string | null;\n /** \"system\" | \"custom\" */\n type?: string;\n key: string;\n name: string;\n description: string | null;\n isSystem?: boolean;\n isDefault?: boolean;\n isActive: boolean;\n permissions: RolePermission[];\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RoleAssignment = {\n id: string;\n roleDefinitionId?: string | null;\n customRoleId?: string | null;\n roleDefinition?: Role | null;\n customRole?: Role | null;\n};\n\nexport type OrganizationMember = {\n id: string;\n organizationId?: string;\n userId?: string;\n createdAt?: string | Date;\n user: User;\n roleAssignments?: RoleAssignment[];\n};\n\nexport type OrganizationOwnedApplication = {\n id: string;\n name: string;\n description: string | null;\n imageUrl: string | null;\n type?: OAuthClientType;\n organizationId: string;\n isFirstParty: boolean;\n ssoEnabled: boolean;\n status?: \"active\" | \"inactive\" | \"suspended\";\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type Organization = {\n id: string;\n name: string;\n description: string | null;\n slug: string;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n status: OrganizationStatus;\n members?: OrganizationMember[];\n ownedApplications?: OrganizationOwnedApplication[];\n applicationLinks?: Array<{\n id: string;\n status: OrganizationStatus;\n createdAt?: string | Date;\n application: OrganizationOwnedApplication;\n }>;\n createdAt: string | Date;\n updatedAt: string | Date;\n};\n\nexport type SessionApplication = {\n id: string;\n createdAt: string | Date;\n expiresAt: string | Date;\n application: {\n id: string;\n name: string;\n organizationId: string;\n };\n};\n\nexport type UserSession = {\n id: string;\n userId: string;\n organizationId: string | null;\n deviceAgent: string | null;\n deviceId: string | null;\n deviceName: string | null;\n ip: string | null;\n authState?: unknown;\n authTime?: string | Date;\n expiresAt: string | Date;\n createdAt: string | Date;\n updatedAt: string | Date;\n user?: User;\n applicationSessions?: SessionApplication[];\n};\n\nexport type UserInput = {\n name?: string | null;\n email?: string;\n phone?: string | null;\n imageUrl?: string | null;\n password?: string;\n organizationId?: string | null;\n status?: UserStatus;\n};\n\nexport type OrganizationInput = {\n name: string;\n description?: string | null;\n slug: string;\n domain?: string | null;\n imageUrl?: string | null;\n faviconUrl?: string | null;\n};\n\nexport type OrganizationUpdateInput = Partial<OrganizationInput> & {\n status?: OrganizationStatus;\n};\n\nexport type RoleInput = {\n organizationId: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n permissionDefinitionIds?: string[];\n};\n\nexport type RoleUpdateInput = {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n permissionDefinitionIds?: string[];\n};\n\nexport type PermissionInput = {\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n category?: string | null;\n};\n\nexport type PermissionUpdateInput = {\n name?: string;\n description?: string | null;\n category?: string | null;\n isActive?: boolean;\n};\n\nexport type SignInOptions = {\n redirectTo?: string;\n authorizationFlowId?: string;\n};\n\nexport type SignInInput = SignInOptions | MouseEvent<HTMLElement>;\n\nexport type CallbackUrlOptions = SignInOptions & {\n callbackUrl?: string;\n};\n\nexport type PermissionCheckOptions = {\n permission: string;\n organizationId?: string | null;\n applicationId?: string | null;\n resourceId?: string | null;\n};\n\nexport type LoginResponse = {\n user: User;\n redirectTo?: string | null;\n};\n\nexport type RegisterResponse = User;\n\nexport type GeekappsAuthProviderProps = {\n children: ReactNode;\n basePath?: string;\n initialUser?: User | null;\n initialOrganizations?: Organization[];\n initialCurrentOrgId?: string | null;\n};\n\ntype RequestOptions = {\n body?: unknown;\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n};\n\nfunction normalizeBasePath(basePath: string) {\n return basePath.endsWith(\"/\") ? basePath.slice(0, -1) : basePath;\n}\n\nfunction buildUrl(basePath: string, path: string) {\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${normalizeBasePath(basePath)}${normalizedPath}`;\n}\n\nasync function parseError(response: Response) {\n const data = await response.json().catch(() => null);\n return (\n data?.error_description ??\n data?.error ??\n data?.message ??\n `Request failed with status ${response.status}`\n );\n}\n\nfunction redirectTo(path: string) {\n window.location.assign(path);\n}\n\nfunction isMouseEvent(value: unknown): value is MouseEvent<HTMLElement> {\n return Boolean(value && typeof value === \"object\" && \"preventDefault\" in value);\n}\n\nfunction normalizeSignInOptions(input?: SignInInput): SignInOptions | undefined {\n if (!input) return undefined;\n if (isMouseEvent(input)) {\n input.preventDefault();\n return undefined;\n }\n return input;\n}\n\n\ntype ClientActionOptions = {\n basePath?: string;\n};\n\nasync function clientRequest<T>(\n path: string,\n options: RequestOptions = {},\n basePath = \"/api/auth\",\n): Promise<T> {\n const response = await fetch(buildUrl(basePath, path), {\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n method: options.method ?? \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(await parseError(response));\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n}\n\nasync function toStandaloneAuthResult<T>(\n fn: () => Promise<T>,\n): Promise<AuthResult<T>> {\n try {\n return {\n success: true,\n data: await fn(),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Auth request failed\",\n };\n }\n}\n\nexport async function loginWithPassword(\n params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<LoginResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<LoginResponse>(\n \"/login/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo ?? data.redirectTo) {\n redirectTo(params.redirectTo ?? data.redirectTo!);\n }\n\n return data;\n });\n}\n\nexport async function registerWithPassword(\n params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<RegisterResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<RegisterResponse>(\n \"/register/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo) {\n redirectTo(params.redirectTo);\n }\n\n return data;\n });\n}\n\nexport function startGoogleLogin(\n params?: CallbackUrlOptions,\n options?: ClientActionOptions,\n) {\n const basePath = options?.basePath ?? \"/api/auth\";\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n\n if (params?.callbackUrl) {\n url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n }\n\n if (params?.redirectTo) {\n url.searchParams.set(\"redirectTo\", params.redirectTo);\n }\n\n if (params?.authorizationFlowId) {\n url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n }\n\n redirectTo(url.toString());\n}\n\nexport async function requestPasswordlessLink(\n params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult> {\n return toStandaloneAuthResult(() =>\n clientRequest(\n \"/passwordless/link\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n ),\n );\n}\n\nexport type GeekappsAuthContextValue = {\n basePath: string;\n user: User | null;\n isLoading: boolean;\n accounts: ConnectedAccount[];\n isLoadingAccounts: boolean;\n organizations: Organization[];\n currentOrg: Organization | null;\n currentOrgId: string | null;\n isLoadingOrganizations: boolean;\n\n request: <T>(path: string, options?: RequestOptions) => Promise<T>;\n\n signIn: (options?: SignInInput) => Promise<void>;\n signUp: (options?: SignInInput) => Promise<void>;\n addAccount: (options?: SignInInput) => Promise<void>;\n signOut: () => Promise<void>;\n signOutAll: () => Promise<void>;\n refreshUser: () => Promise<void>;\n refreshAccounts: () => Promise<void>;\n switchAccount: (sessionId: string, options?: SignInOptions) => Promise<void>;\n\n loginWithPassword: (params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n }) => Promise<AuthResult<LoginResponse>>;\n registerWithPassword: (params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n }) => Promise<AuthResult<RegisterResponse>>;\n startGoogleLogin: (params?: CallbackUrlOptions) => void;\n requestPasswordlessLink: (params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n }) => Promise<AuthResult>;\n\n refreshOrganizations: () => Promise<void>;\n setCurrentOrg: (organizationId: string | null) => Promise<void>;\n createOrganization: (input: OrganizationInput) => Promise<AuthResult<Organization>>;\n updateOrganization: (id: string, input: OrganizationUpdateInput) => Promise<AuthResult<Organization>>;\n deleteOrganization: (id: string) => Promise<AuthResult<null>>;\n hasPermission: (options: PermissionCheckOptions) => Promise<boolean>;\n\n listUsers: (params?: { organizationId?: string | null }) => Promise<User[]>;\n getUser: (id: string) => Promise<User>;\n createUser: (input: UserInput) => Promise<AuthResult<User>>;\n updateUser: (id: string, input: UserInput) => Promise<AuthResult<User>>;\n deleteUser: (id: string) => Promise<AuthResult<null>>;\n\n listRoles: (params: { organizationId?: string; applicationId?: string; type?: \"system\" | \"custom\" | \"all\" }) => Promise<{ systemRoles: Role[]; customRoles: Role[] }>;\n getRole: (id: string, type: \"system\" | \"custom\") => Promise<Role>;\n createRole: (input: RoleInput) => Promise<AuthResult<Role>>;\n updateRole: (id: string, input: RoleUpdateInput) => Promise<AuthResult<Role>>;\n deleteRole: (id: string) => Promise<AuthResult<null>>;\n\n listPermissions: (params: { applicationId?: string; roleId?: string | null }) => Promise<Permission[]>;\n createPermission: (input: PermissionInput) => Promise<AuthResult<Permission>>;\n updatePermission: (id: string, input: PermissionUpdateInput) => Promise<AuthResult<Permission>>;\n deletePermission: (id: string) => Promise<AuthResult<null>>;\n\n listUserSessions: (params?: { userId?: string; organizationId?: string | null }) => Promise<UserSession[]>;\n revokeUserSession: (sessionId: string) => Promise<AuthResult<null>>;\n};\n\nexport type UseOrgResult = Pick<\n GeekappsAuthContextValue,\n | \"organizations\"\n | \"currentOrg\"\n | \"currentOrgId\"\n | \"isLoadingOrganizations\"\n | \"refreshOrganizations\"\n | \"setCurrentOrg\"\n | \"createOrganization\"\n | \"updateOrganization\"\n | \"deleteOrganization\"\n | \"hasPermission\"\n>;\n\nexport type UseAccountsResult = Pick<\n GeekappsAuthContextValue,\n \"accounts\" | \"addAccount\" | \"isLoadingAccounts\" | \"refreshAccounts\" | \"switchAccount\"\n>;\n\nexport type UseUsersResult = Pick<\n GeekappsAuthContextValue,\n \"listUsers\" | \"getUser\" | \"createUser\" | \"updateUser\" | \"deleteUser\"\n>;\n\nexport type UseRolesResult = Pick<\n GeekappsAuthContextValue,\n \"listRoles\" | \"getRole\" | \"createRole\" | \"updateRole\" | \"deleteRole\"\n>;\n\nexport type UsePermissionsResult = Pick<\n GeekappsAuthContextValue,\n \"listPermissions\" | \"createPermission\" | \"updatePermission\" | \"deletePermission\"\n>;\n\nexport type UseSessionsResult = Pick<\n GeekappsAuthContextValue,\n \"listUserSessions\" | \"revokeUserSession\"\n>;\n\nconst GeekappsAuthContext = createContext<GeekappsAuthContextValue | null>(null);\n\nexport function GeekappsAuthProvider({\n children,\n basePath = \"/api/auth\",\n initialUser = null,\n initialOrganizations = [],\n initialCurrentOrgId = null,\n}: GeekappsAuthProviderProps): ReactElement {\n const [user, setUser] = useState<User | null>(initialUser);\n const [isLoading, setIsLoading] = useState(true);\n const [accounts, setAccounts] = useState<ConnectedAccount[]>([]);\n const [isLoadingAccounts, setIsLoadingAccounts] = useState(true);\n const [organizations, setOrganizations] = useState<Organization[]>(initialOrganizations);\n const [currentOrgId, setCurrentOrgId] = useState<string | null>(initialCurrentOrgId);\n const [isLoadingOrganizations, setIsLoadingOrganizations] = useState(true);\n\n const request = useCallback(\n async <T,>(path: string, options: RequestOptions = {}) => {\n const response = await fetch(buildUrl(basePath, path), {\n method: options.method ?? \"GET\",\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n\n if (!response.ok) {\n throw new Error(await parseError(response));\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n },\n [basePath],\n );\n\n const refreshUser = useCallback(async () => {\n setIsLoading(true);\n try {\n const { user: u } = await getMe();\n setUser(u);\n } catch {\n setUser(null);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const refreshAccounts = useCallback(async () => {\n setIsLoadingAccounts(true);\n try {\n const { accounts: a } = await getAccounts();\n setAccounts(a);\n } catch {\n setAccounts([]);\n } finally {\n setIsLoadingAccounts(false);\n }\n }, []);\n\n const refreshOrganizations = useCallback(async () => {\n setIsLoadingOrganizations(true);\n try {\n const { organizations: orgs, currentOrgId: nextCurrentOrgId } = await getOrganizations();\n setOrganizations(orgs);\n setCurrentOrgId((current) => {\n if (nextCurrentOrgId !== undefined) return nextCurrentOrgId ?? null;\n if (current && orgs.some((org) => org.id === current)) return current;\n return orgs[0]?.id ?? null;\n });\n } catch {\n setOrganizations([]);\n setCurrentOrgId(null);\n } finally {\n setIsLoadingOrganizations(false);\n }\n }, []);\n\n useEffect(() => {\n void refreshUser();\n void refreshAccounts();\n void refreshOrganizations();\n }, [refreshAccounts, refreshOrganizations, refreshUser]);\n\n const currentOrg = useMemo(\n () => organizations.find((organization) => organization.id === currentOrgId) ?? null,\n [currentOrgId, organizations],\n );\n\n const setCurrentOrg = useCallback(\n async (organizationId: string | null) => {\n await request(\"/organizations/active\", {\n method: \"POST\",\n body: { organizationId },\n });\n setCurrentOrgId(organizationId);\n },\n [request],\n );\n\n const signIn = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-in\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signUp = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-up\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const addAccount = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/add-account\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signOut = useCallback(async () => {\n await request(\"/sign-out\", { method: \"POST\" });\n setUser(null);\n await refreshAccounts();\n }, [refreshAccounts, request]);\n\n const signOutAll = useCallback(async () => {\n await request(\"/sign-out-all\", { method: \"POST\" });\n setUser(null);\n setAccounts([]);\n }, [request]);\n\n const switchAccount = useCallback(\n async (sessionId: string, options?: SignInOptions) => {\n await request(\"/accounts/switch\", {\n method: \"POST\",\n body: { sessionId },\n });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (options?.redirectTo) redirectTo(options.redirectTo);\n },\n [refreshAccounts, refreshOrganizations, refreshUser, request],\n );\n\n async function toAuthResult<T>(fn: () => Promise<T>): Promise<AuthResult<T>> {\n try {\n return { success: true, data: await fn() };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : \"Unexpected error\" };\n }\n }\n\n const value = useMemo<GeekappsAuthContextValue>(\n () => ({\n basePath,\n user,\n isLoading,\n accounts,\n isLoadingAccounts,\n organizations,\n currentOrg,\n currentOrgId,\n isLoadingOrganizations,\n request,\n signIn,\n signUp,\n addAccount,\n signOut,\n signOutAll,\n refreshUser,\n refreshAccounts,\n switchAccount,\n loginWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<LoginResponse>(\"/login/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo ?? data.redirectTo) redirectTo(params.redirectTo ?? data.redirectTo!);\n return data;\n }),\n registerWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<RegisterResponse>(\"/register/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo) redirectTo(params.redirectTo);\n return data;\n }),\n startGoogleLogin: (params) => {\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n if (params?.callbackUrl) url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n if (params?.redirectTo) url.searchParams.set(\"redirectTo\", params.redirectTo);\n if (params?.authorizationFlowId) url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n redirectTo(url.toString());\n },\n requestPasswordlessLink: (params) =>\n toAuthResult(() => request(\"/passwordless/link\", { method: \"POST\", body: params })),\n refreshOrganizations,\n setCurrentOrg,\n createOrganization: (input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(\"/organizations\", { method: \"POST\", body: input });\n await refreshOrganizations();\n setCurrentOrgId(organization.id);\n return organization;\n }),\n updateOrganization: (id, input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(`/organizations/${id}`, { method: \"PATCH\", body: input });\n await refreshOrganizations();\n return organization;\n }),\n deleteOrganization: (id) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${id}`, { method: \"DELETE\" });\n await refreshOrganizations();\n return null;\n }),\n hasPermission: async (options) => {\n try {\n const data = await request<{ allowed: boolean }>(\"/permissions/check\", {\n method: \"POST\",\n body: options,\n });\n return data.allowed;\n } catch {\n return false;\n }\n },\n listUsers: (params) => {\n const query = new URLSearchParams();\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<User[]>(`/users${query.size ? `?${query.toString()}` : \"\"}`);\n },\n getUser: (id) => request<User>(`/users/${id}`),\n createUser: (input) => toAuthResult(() => request<User>(\"/users\", { method: \"POST\", body: input })),\n updateUser: (id, input) => toAuthResult(() => request<User>(`/users/${id}`, { method: \"PATCH\", body: input })),\n deleteUser: (id) =>\n toAuthResult(async () => {\n await request<null>(`/users/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listRoles: (params) => {\n const query = new URLSearchParams();\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n if (params?.applicationId) query.set(\"applicationId\", params.applicationId);\n if (params?.type) query.set(\"type\", params.type);\n return request<{ systemRoles: Role[]; customRoles: Role[] }>(`/roles${query.size ? `?${query.toString()}` : \"\"}`);\n },\n getRole: (id, type) => request<Role>(type === \"custom\" ? `/roles/custom/${id}` : `/roles/definitions/${id}`),\n createRole: (input) => toAuthResult(() => request<Role>(\"/roles\", { method: \"POST\", body: input })),\n updateRole: (id, input) => toAuthResult(() => request<Role>(`/roles/custom/${id}`, { method: \"PATCH\", body: input })),\n deleteRole: (id) =>\n toAuthResult(async () => {\n await request<null>(`/roles/custom/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listPermissions: (params) => {\n const query = new URLSearchParams();\n if (params?.applicationId) query.set(\"applicationId\", params.applicationId);\n if (params?.roleId) query.set(\"roleId\", params.roleId);\n return request<Permission[]>(`/permissions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n createPermission: (input) =>\n toAuthResult(() => request<Permission>(\"/permissions\", { method: \"POST\", body: input })),\n updatePermission: (id, input) =>\n toAuthResult(() => request<Permission>(`/permissions/${id}`, { method: \"PATCH\", body: input })),\n deletePermission: (id) =>\n toAuthResult(async () => {\n await request<null>(`/permissions/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listUserSessions: (params) => {\n const query = new URLSearchParams();\n if (params?.userId) query.set(\"userId\", params.userId);\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<UserSession[]>(`/sessions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n revokeUserSession: (sessionId) =>\n toAuthResult(async () => {\n await request<null>(`/sessions/${sessionId}`, { method: \"DELETE\" });\n return null;\n }),\n }),\n [\n accounts,\n addAccount,\n basePath,\n currentOrg,\n currentOrgId,\n isLoading,\n isLoadingAccounts,\n isLoadingOrganizations,\n organizations,\n refreshAccounts,\n refreshOrganizations,\n refreshUser,\n request,\n setCurrentOrg,\n signIn,\n signOut,\n signOutAll,\n signUp,\n switchAccount,\n user,\n ],\n );\n\n return <GeekappsAuthContext.Provider value={value}>{children}</GeekappsAuthContext.Provider>;\n}\n\nexport function useAuth(): GeekappsAuthContextValue {\n const context = useContext(GeekappsAuthContext);\n if (!context) throw new Error(\"useAuth must be used inside GeekappsAuthProvider\");\n return context;\n}\n\nexport function useOrg(): UseOrgResult {\n const context = useAuth();\n return {\n organizations: context.organizations,\n currentOrg: context.currentOrg,\n currentOrgId: context.currentOrgId,\n isLoadingOrganizations: context.isLoadingOrganizations,\n refreshOrganizations: context.refreshOrganizations,\n setCurrentOrg: context.setCurrentOrg,\n createOrganization: context.createOrganization,\n updateOrganization: context.updateOrganization,\n deleteOrganization: context.deleteOrganization,\n hasPermission: context.hasPermission,\n };\n}\n\nexport function useAccounts(): UseAccountsResult {\n const context = useAuth();\n return {\n accounts: context.accounts,\n addAccount: context.addAccount,\n isLoadingAccounts: context.isLoadingAccounts,\n refreshAccounts: context.refreshAccounts,\n switchAccount: context.switchAccount,\n };\n}\n\nexport function useUsers(): UseUsersResult {\n const context = useAuth();\n return {\n listUsers: context.listUsers,\n getUser: context.getUser,\n createUser: context.createUser,\n updateUser: context.updateUser,\n deleteUser: context.deleteUser,\n };\n}\n\nexport function useRoles(): UseRolesResult {\n const context = useAuth();\n return {\n listRoles: context.listRoles,\n getRole: context.getRole,\n createRole: context.createRole,\n updateRole: context.updateRole,\n deleteRole: context.deleteRole,\n };\n}\n\nexport function usePermissions(): UsePermissionsResult {\n const context = useAuth();\n return {\n listPermissions: context.listPermissions,\n createPermission: context.createPermission,\n updatePermission: context.updatePermission,\n deletePermission: context.deletePermission,\n };\n}\n\nexport function useSessions(): UseSessionsResult {\n const context = useAuth();\n return {\n listUserSessions: context.listUserSessions,\n revokeUserSession: context.revokeUserSession,\n };\n}\n\n// ── Service Accounts ─────────────────────────────────────────────────────────\n\nexport type ServiceAccount = {\n id: string;\n membershipId: string;\n organizationId: string;\n applicationId: string | null;\n name: string;\n status: \"active\" | \"inactive\" | \"suspended\";\n serviceId: string | null;\n roleAssignment: { role: { id: string; key: string; name: string } } | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type ServiceAccountWithSecret = ServiceAccount & { serviceSecret: string };\n\nexport type CreateServiceAccountInput = {\n organizationId: string;\n applicationId?: string;\n name: string;\n description?: string;\n roleId?: string;\n};\n\nexport type UseServiceAccountResult = {\n listServiceAccounts: (params: { organizationId: string; applicationId?: string }) => Promise<ServiceAccount[]>;\n createServiceAccount: (input: CreateServiceAccountInput) => Promise<ServiceAccountWithSecret>;\n updateServiceAccountRole: (id: string, roleId: string | null) => Promise<void>;\n revokeServiceAccount: (id: string) => Promise<void>;\n rotateServiceAccountSecret: (id: string) => Promise<{ serviceId: string; serviceSecret: string }>;\n deleteServiceAccount: (id: string) => Promise<void>;\n};\n\nexport function useServiceAccount(): UseServiceAccountResult {\n const { request } = useAuth();\n\n const listServiceAccounts = useCallback(\n (params: { organizationId: string; applicationId?: string }) => {\n const query = new URLSearchParams({ organizationId: params.organizationId });\n if (params.applicationId) query.set(\"applicationId\", params.applicationId);\n return request<ServiceAccount[]>(`/service-accounts?${query.toString()}`);\n },\n [request],\n );\n\n const createServiceAccount = useCallback(\n (input: CreateServiceAccountInput) =>\n request<ServiceAccountWithSecret>(\"/service-accounts\", { method: \"POST\", body: input }),\n [request],\n );\n\n const updateServiceAccountRole = useCallback(\n async (id: string, roleId: string | null) => {\n await request<void>(`/service-accounts/${id}`, { method: \"PATCH\", body: { roleId } });\n },\n [request],\n );\n\n const revokeServiceAccount = useCallback(\n async (id: string) => {\n await request<void>(`/service-accounts/${id}/revoke`, { method: \"POST\" });\n },\n [request],\n );\n\n const rotateServiceAccountSecret = useCallback(\n (id: string) =>\n request<{ serviceId: string; serviceSecret: string }>(`/service-accounts/${id}/rotate-secret`, {\n method: \"POST\",\n }),\n [request],\n );\n\n const deleteServiceAccount = useCallback(\n async (id: string) => {\n await request<null>(`/service-accounts/${id}`, { method: \"DELETE\" });\n },\n [request],\n );\n\n return {\n listServiceAccounts,\n createServiceAccount,\n updateServiceAccountRole,\n revokeServiceAccount,\n rotateServiceAccountSecret,\n deleteServiceAccount,\n };\n}\n","\"use server\";\n\nimport { cookies } from \"next/headers\";\nimport type { ConnectedAccount, Organization, User } from \"./client\";\n\n// ── cookie helpers (duplicated from server.ts to keep this file self-contained) ──\n\nfunction env(name: string) {\n const value = process.env[name];\n return value && value.trim().length > 0 ? value : undefined;\n}\n\nfunction normalizeBaseUrl(url: string) {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction resolveIssuer() {\n return normalizeBaseUrl(\n env(\"GEEKAPPS_AUTH_ISSUER\") ?? env(\"GEEKAPPS_AUTH_API_URL\") ?? \"http://localhost:3020\",\n );\n}\n\nfunction getServerClientHeaders() {\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\");\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\");\n\n return clientId && clientSecret\n ? {\n \"x-geekapps-client-id\": clientId,\n \"x-geekapps-client-secret\": clientSecret,\n }\n : {};\n}\n\nfunction hashClientId(clientId: string): string {\n let h = 5381;\n for (let i = 0; i < clientId.length; i++) {\n h = ((h << 5) + h) ^ (clientId.charCodeAt(i) & 0xff);\n h = h >>> 0;\n }\n return h.toString(16).padStart(8, \"0\");\n}\n\nfunction deriveCookiePrefix(): string {\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\") ?? \"\";\n if (!clientId) return \"gk\";\n return `gk_${hashClientId(clientId)}`;\n}\n\ntype SlotMeta = { id: string; sid?: string; n?: string; e?: string; p?: string };\n\nfunction decodeMeta(value: string): SlotMeta | null {\n try {\n const m = JSON.parse(Buffer.from(value, \"base64url\").toString(\"utf8\")) as SlotMeta;\n return m.id ? m : null;\n } catch {\n return null;\n }\n}\n\nasync function getCookieNames() {\n const prefix = deriveCookiePrefix();\n return {\n active: `${prefix}_active`,\n count: `${prefix}_count`,\n activeOrganizationId: `${prefix}_ao`,\n slotMeta: (n: number) => `${prefix}_m${n}`,\n slotAt: (n: number) => `${prefix}_at${n}`,\n slotRt: (n: number) => `${prefix}_rt${n}`,\n };\n}\n\nasync function getActiveAccessToken(): Promise<string | null> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 0;\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n if (count === 0) return null;\n const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;\n return cookieStore.get(cn.slotAt(idx))?.value ?? null;\n}\n\nasync function getActiveRefreshToken(): Promise<string | null> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 0;\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n if (count === 0) return null;\n const idx = activeIdx >= 1 && activeIdx <= count ? activeIdx : 1;\n return cookieStore.get(cn.slotRt(idx))?.value ?? null;\n}\n\nasync function refreshAndSaveTokens(): Promise<string | null> {\n const refreshToken = await getActiveRefreshToken();\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\") ?? \"\";\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\") ?? \"\";\n if (!refreshToken || !clientId) return null;\n\n const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString(\"base64\");\n const response = await fetch(`${resolveIssuer()}/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/x-www-form-urlencoded\",\n authorization: `Basic ${basicAuth}`,\n },\n body: new URLSearchParams({ grant_type: \"refresh_token\", refresh_token: refreshToken }),\n cache: \"no-store\",\n });\n\n if (!response.ok) return null;\n\n const data = await response.json().catch(() => null) as Record<string, unknown> | null;\n if (!data) return null;\n\n const newAccessToken =\n (data.accessToken ?? data.access_token) as string | undefined;\n const newRefreshToken =\n (data.refreshToken ?? data.refresh_token) as string | undefined;\n\n if (!newAccessToken) return null;\n\n // Update the active slot cookies\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const raw = cookieStore.get(cn.active)?.value;\n const activeIdx = raw ? Number.parseInt(raw, 10) : 1;\n const opts = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n };\n cookieStore.set(cn.slotAt(activeIdx), newAccessToken, opts);\n if (newRefreshToken) cookieStore.set(cn.slotRt(activeIdx), newRefreshToken, opts);\n // Update public token cookie\n cookieStore.set(`${deriveCookiePrefix()}_tp`, newAccessToken, {\n httpOnly: false,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\",\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n });\n\n return newAccessToken;\n}\n\nasync function authFetch<T>(path: string): Promise<T> {\n let accessToken = await getActiveAccessToken();\n if (!accessToken) throw new Error(\"Not authenticated\");\n\n const issuer = resolveIssuer();\n const doFetch = (token: string) =>\n fetch(`${issuer}${path}`, {\n headers: {\n authorization: `Bearer ${token}`,\n ...getServerClientHeaders(),\n } as HeadersInit,\n cache: \"no-store\",\n });\n\n let response = await doFetch(accessToken);\n\n if (response.status === 401) {\n const newToken = await refreshAndSaveTokens();\n if (!newToken) throw new Error(\"Session expired\");\n response = await doFetch(newToken);\n }\n\n if (!response.ok) {\n const err = await response.json().catch(() => null) as Record<string, unknown> | null;\n throw new Error((err?.error_description ?? err?.error ?? err?.message ?? `Auth error ${response.status}`) as string);\n }\n\n if (response.status === 204) return null as T;\n return response.json() as Promise<T>;\n}\n\n// ── Exported server actions ────────────────────────────────────────────────────\n\nexport async function getMe(): Promise<{ user: User | null }> {\n try {\n const data = await authFetch<{ user: User | null } | User | null>(\"/auth/me\");\n if (!data) return { user: null };\n if (typeof data === \"object\" && \"user\" in data) return data as { user: User | null };\n return { user: data as User | null };\n } catch {\n return { user: null };\n }\n}\n\nexport async function getAccounts(): Promise<{ accounts: ConnectedAccount[] }> {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const countRaw = cookieStore.get(cn.count)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n const activeRaw = cookieStore.get(cn.active)?.value;\n const activeIdx = activeRaw ? Number.parseInt(activeRaw, 10) : 0;\n\n const accounts: ConnectedAccount[] = [];\n for (let i = 1; i <= count; i++) {\n const at = cookieStore.get(cn.slotAt(i))?.value;\n if (!at) continue;\n const meta = decodeMeta(cookieStore.get(cn.slotMeta(i))?.value ?? \"\");\n if (!meta) continue;\n accounts.push({\n id: meta.id,\n sessionId: meta.sid ?? meta.id,\n isActive: i === activeIdx,\n user: {\n id: meta.id,\n name: meta.n ?? null,\n email: meta.e ?? \"\",\n imageUrl: meta.p ?? null,\n phone: null,\n },\n });\n }\n\n return { accounts };\n}\n\nexport async function getOrganizations(): Promise<{ organizations: Organization[]; currentOrgId?: string | null }> {\n try {\n const cookieStore = await cookies();\n const cn = await getCookieNames();\n const activeOrgId = cookieStore.get(cn.activeOrganizationId)?.value ?? null;\n const data = await authFetch<Organization[] | { organizations: Organization[] }>(\"/organizations\");\n const organizations = Array.isArray(data) ? data : (data as { organizations: Organization[] }).organizations;\n const resolvedOrgId = activeOrgId ?? organizations[0]?.id ?? null;\n return { organizations, currentOrgId: resolvedOrgId };\n } catch (err) {\n console.error(\"[getOrganizations] error:\", err);\n return { organizations: [] };\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,16 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+
3
+ type AuthMiddlewareConfig = {
4
+ issuer?: string;
5
+ basePath?: string;
6
+ /**
7
+ * @deprecated cookiePrefix is now auto-derived from GEEKAPPS_AUTH_CLIENT_ID.
8
+ * This field is kept for backwards compatibility but is ignored.
9
+ */
10
+ cookiePrefix?: string;
11
+ secureCookies?: boolean;
12
+ cookieDomain?: string;
13
+ };
14
+ declare function createAuthMiddleware(input?: AuthMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
15
+
16
+ export { type AuthMiddlewareConfig, createAuthMiddleware };
@@ -0,0 +1,173 @@
1
+ // src/middleware.ts
2
+ import { NextResponse } from "next/server";
3
+ import { createRemoteJWKSet, jwtVerify } from "jose";
4
+ function env(name) {
5
+ const value = process.env[name];
6
+ return value && value.trim().length > 0 ? value : void 0;
7
+ }
8
+ function normalizeBaseUrl(url) {
9
+ return url.replace(/\/$/, "");
10
+ }
11
+ function normalizeBasePath(path = "/api/auth") {
12
+ if (!path.startsWith("/")) return `/${path}`;
13
+ return path.replace(/\/$/, "");
14
+ }
15
+ function resolveIssuer(input) {
16
+ return normalizeBaseUrl(
17
+ input.issuer ?? env("GEEKAPPS_AUTH_ISSUER") ?? env("GEEKAPPS_AUTH_API_URL") ?? "http://localhost:3020"
18
+ );
19
+ }
20
+ function hashClientId(clientId) {
21
+ let h = 5381;
22
+ for (let i = 0; i < clientId.length; i++) {
23
+ h = (h << 5) + h ^ clientId.charCodeAt(i) & 255;
24
+ h = h >>> 0;
25
+ }
26
+ return h.toString(16).padStart(8, "0");
27
+ }
28
+ function deriveCookiePrefix(clientId) {
29
+ if (!clientId) return "gk";
30
+ return `gk_${hashClientId(clientId)}`;
31
+ }
32
+ var MAX_REFRESH_ATTEMPTS = 3;
33
+ function decodeJwtExp(token) {
34
+ try {
35
+ const parts = token.split(".");
36
+ if (parts.length !== 3) return null;
37
+ const payload = parts[1];
38
+ const padded = payload + "=".repeat((4 - payload.length % 4) % 4);
39
+ const decoded = JSON.parse(atob(padded));
40
+ return typeof decoded.exp === "number" ? decoded.exp : null;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+ function requestOrigin(request) {
46
+ const forwardedProto = request.headers.get("x-forwarded-proto");
47
+ const forwardedHost = request.headers.get("x-forwarded-host");
48
+ const host = forwardedHost ?? request.headers.get("host");
49
+ if (host) {
50
+ return `${forwardedProto ?? request.nextUrl.protocol.replace(":", "")}://${host}`;
51
+ }
52
+ return request.nextUrl.origin;
53
+ }
54
+ var _jwksCache = /* @__PURE__ */ new Map();
55
+ function getRemoteJWKS(issuer) {
56
+ if (!_jwksCache.has(issuer)) {
57
+ _jwksCache.set(issuer, createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`)));
58
+ }
59
+ return _jwksCache.get(issuer);
60
+ }
61
+ async function verifyAccessToken(token, issuer) {
62
+ try {
63
+ await jwtVerify(token, getRemoteJWKS(issuer), { algorithms: ["RS256"], issuer });
64
+ return true;
65
+ } catch {
66
+ return false;
67
+ }
68
+ }
69
+ function createAuthMiddleware(input = {}) {
70
+ const issuer = resolveIssuer(input);
71
+ const basePath = normalizeBasePath(input.basePath);
72
+ const clientId = env("GEEKAPPS_AUTH_CLIENT_ID");
73
+ const prefix = deriveCookiePrefix(clientId);
74
+ const activeCookie = `${prefix}_active`;
75
+ const countCookie = `${prefix}_count`;
76
+ const tokenPubCookie = `${prefix}_tp`;
77
+ const slotAt = (n) => `${prefix}_at${n}`;
78
+ const slotRt = (n) => `${prefix}_rt${n}`;
79
+ return async function authMiddleware(request) {
80
+ const countRaw = request.cookies.get(countCookie)?.value;
81
+ const count = countRaw ? Number.parseInt(countRaw, 10) : 0;
82
+ const activeRaw = request.cookies.get(activeCookie)?.value;
83
+ let activeIdx = activeRaw ? Number.parseInt(activeRaw, 10) : 1;
84
+ if (Number.isNaN(activeIdx) || activeIdx < 1 || activeIdx > count) {
85
+ activeIdx = count > 0 ? 1 : 0;
86
+ }
87
+ const accessToken = activeIdx > 0 ? request.cookies.get(slotAt(activeIdx))?.value ?? null : null;
88
+ const refreshToken = activeIdx > 0 ? request.cookies.get(slotRt(activeIdx))?.value ?? null : null;
89
+ const origin = requestOrigin(request);
90
+ const signInUrl = new URL(`${origin}${basePath}/sign-in`);
91
+ const redirectTo = request.nextUrl.pathname + request.nextUrl.search;
92
+ if (redirectTo && redirectTo !== "/") {
93
+ signInUrl.searchParams.set("redirectTo", redirectTo);
94
+ }
95
+ if (!accessToken && !refreshToken) {
96
+ return NextResponse.redirect(signInUrl);
97
+ }
98
+ const exp = accessToken ? decodeJwtExp(accessToken) : null;
99
+ const nowSec = Math.floor(Date.now() / 1e3);
100
+ const expiredOrMissing = !exp || exp - nowSec < 60;
101
+ if (!expiredOrMissing) {
102
+ const valid = await verifyAccessToken(accessToken, issuer);
103
+ if (valid) return NextResponse.next();
104
+ }
105
+ if (!refreshToken) {
106
+ return NextResponse.redirect(signInUrl);
107
+ }
108
+ const clientSecret = env("GEEKAPPS_AUTH_CLIENT_SECRET") ?? "";
109
+ const basicAuth = btoa(`${clientId ?? ""}:${clientSecret}`);
110
+ let newAccessToken = null;
111
+ let newRefreshToken = null;
112
+ for (let attempt = 1; attempt <= MAX_REFRESH_ATTEMPTS; attempt++) {
113
+ try {
114
+ const refreshResponse = await fetch(`${issuer}/auth/refresh`, {
115
+ method: "POST",
116
+ headers: {
117
+ "content-type": "application/x-www-form-urlencoded",
118
+ authorization: `Basic ${basicAuth}`
119
+ },
120
+ body: new URLSearchParams({
121
+ grant_type: "refresh_token",
122
+ refresh_token: refreshToken
123
+ }),
124
+ cache: "no-store"
125
+ });
126
+ if (!refreshResponse.ok) break;
127
+ const data = await refreshResponse.json();
128
+ newAccessToken = data.accessToken ?? data.access_token ?? null;
129
+ newRefreshToken = data.refreshToken ?? data.refresh_token ?? null;
130
+ if (newAccessToken) break;
131
+ } catch {
132
+ if (attempt === MAX_REFRESH_ATTEMPTS) break;
133
+ }
134
+ }
135
+ if (!newAccessToken) {
136
+ const response2 = NextResponse.redirect(signInUrl);
137
+ const clearOpts = {
138
+ httpOnly: true,
139
+ secure: input.secureCookies ?? process.env.NODE_ENV === "production",
140
+ sameSite: "lax",
141
+ path: "/",
142
+ maxAge: 0
143
+ };
144
+ response2.cookies.set(slotAt(activeIdx), "", clearOpts);
145
+ response2.cookies.set(slotRt(activeIdx), "", clearOpts);
146
+ response2.cookies.set(`${prefix}_m${activeIdx}`, "", clearOpts);
147
+ response2.cookies.set(tokenPubCookie, "", { ...clearOpts, httpOnly: false });
148
+ response2.cookies.set(activeCookie, "0", clearOpts);
149
+ return response2;
150
+ }
151
+ const cookieOptions = {
152
+ httpOnly: true,
153
+ secure: input.secureCookies ?? process.env.NODE_ENV === "production",
154
+ sameSite: "lax",
155
+ path: "/",
156
+ maxAge: 60 * 60 * 24 * 30,
157
+ ...input.cookieDomain ? { domain: input.cookieDomain } : {}
158
+ };
159
+ const requestHeaders = new Headers(request.headers);
160
+ requestHeaders.set("x-gk-access-token", newAccessToken);
161
+ const response = NextResponse.next({ request: { headers: requestHeaders } });
162
+ response.cookies.set(slotAt(activeIdx), newAccessToken, cookieOptions);
163
+ if (newRefreshToken) response.cookies.set(slotRt(activeIdx), newRefreshToken, cookieOptions);
164
+ if (request.cookies.get(tokenPubCookie)?.value) {
165
+ response.cookies.set(tokenPubCookie, "", { httpOnly: false, maxAge: 0, path: "/" });
166
+ }
167
+ return response;
168
+ };
169
+ }
170
+ export {
171
+ createAuthMiddleware
172
+ };
173
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { NextResponse, type NextRequest } from \"next/server\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\n\nexport type AuthMiddlewareConfig = {\n issuer?: string;\n basePath?: string;\n /**\n * @deprecated cookiePrefix is now auto-derived from GEEKAPPS_AUTH_CLIENT_ID.\n * This field is kept for backwards compatibility but is ignored.\n */\n cookiePrefix?: string;\n secureCookies?: boolean;\n cookieDomain?: string;\n};\n\ntype TokenLikeResponse = {\n access_token?: string;\n accessToken?: string;\n refresh_token?: string;\n refreshToken?: string;\n id_token?: string;\n idToken?: string;\n};\n\nfunction env(name: string) {\n const value = process.env[name];\n return value && value.trim().length > 0 ? value : undefined;\n}\n\nfunction normalizeBaseUrl(url: string) {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeBasePath(path = \"/api/auth\") {\n if (!path.startsWith(\"/\")) return `/${path}`;\n return path.replace(/\\/$/, \"\");\n}\n\nfunction resolveIssuer(input: AuthMiddlewareConfig) {\n return normalizeBaseUrl(\n input.issuer ??\n env(\"GEEKAPPS_AUTH_ISSUER\") ??\n env(\"GEEKAPPS_AUTH_API_URL\") ??\n \"http://localhost:3020\",\n );\n}\n\nfunction hashClientId(clientId: string): string {\n let h = 5381;\n for (let i = 0; i < clientId.length; i++) {\n h = ((h << 5) + h) ^ (clientId.charCodeAt(i) & 0xff);\n h = h >>> 0;\n }\n return h.toString(16).padStart(8, \"0\");\n}\n\nfunction deriveCookiePrefix(clientId: string | undefined): string {\n if (!clientId) return \"gk\";\n return `gk_${hashClientId(clientId)}`;\n}\n\n\nconst MAX_REFRESH_ATTEMPTS = 3;\n\nfunction decodeJwtExp(token: string): number | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n const payload = parts[1]!;\n const padded = payload + \"=\".repeat((4 - (payload.length % 4)) % 4);\n const decoded = JSON.parse(atob(padded)) as { exp?: number };\n return typeof decoded.exp === \"number\" ? decoded.exp : null;\n } catch {\n return null;\n }\n}\n\nfunction requestOrigin(request: NextRequest) {\n const forwardedProto = request.headers.get(\"x-forwarded-proto\");\n const forwardedHost = request.headers.get(\"x-forwarded-host\");\n const host = forwardedHost ?? request.headers.get(\"host\");\n if (host) {\n return `${forwardedProto ?? request.nextUrl.protocol.replace(\":\", \"\")}://${host}`;\n }\n return request.nextUrl.origin;\n}\n\nconst _jwksCache = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\n\nfunction getRemoteJWKS(issuer: string) {\n if (!_jwksCache.has(issuer)) {\n _jwksCache.set(issuer, createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`)));\n }\n return _jwksCache.get(issuer)!;\n}\n\nasync function verifyAccessToken(token: string, issuer: string): Promise<boolean> {\n try {\n await jwtVerify(token, getRemoteJWKS(issuer), { algorithms: [\"RS256\"], issuer });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function createAuthMiddleware(input: AuthMiddlewareConfig = {}) {\n const issuer = resolveIssuer(input);\n const basePath = normalizeBasePath(input.basePath);\n const clientId = env(\"GEEKAPPS_AUTH_CLIENT_ID\");\n const prefix = deriveCookiePrefix(clientId);\n\n const activeCookie = `${prefix}_active`;\n const countCookie = `${prefix}_count`;\n const tokenPubCookie = `${prefix}_tp`; // legacy — cleared on next refresh\n const slotAt = (n: number) => `${prefix}_at${n}`;\n const slotRt = (n: number) => `${prefix}_rt${n}`;\n\n return async function authMiddleware(request: NextRequest): Promise<NextResponse> {\n const countRaw = request.cookies.get(countCookie)?.value;\n const count = countRaw ? Number.parseInt(countRaw, 10) : 0;\n\n const activeRaw = request.cookies.get(activeCookie)?.value;\n let activeIdx = activeRaw ? Number.parseInt(activeRaw, 10) : 1;\n if (Number.isNaN(activeIdx) || activeIdx < 1 || activeIdx > count) {\n activeIdx = count > 0 ? 1 : 0;\n }\n\n const accessToken = activeIdx > 0 ? (request.cookies.get(slotAt(activeIdx))?.value ?? null) : null;\n const refreshToken = activeIdx > 0 ? (request.cookies.get(slotRt(activeIdx))?.value ?? null) : null;\n\n const origin = requestOrigin(request);\n const signInUrl = new URL(`${origin}${basePath}/sign-in`);\n const redirectTo = request.nextUrl.pathname + request.nextUrl.search;\n if (redirectTo && redirectTo !== \"/\") {\n signInUrl.searchParams.set(\"redirectTo\", redirectTo);\n }\n\n if (!accessToken && !refreshToken) {\n return NextResponse.redirect(signInUrl);\n }\n\n // Fast-path: check exp before hitting JWKS (avoids network on every request)\n const exp = accessToken ? decodeJwtExp(accessToken) : null;\n const nowSec = Math.floor(Date.now() / 1000);\n const expiredOrMissing = !exp || exp - nowSec < 60;\n\n if (!expiredOrMissing) {\n // Verify signature against app-api JWKS\n const valid = await verifyAccessToken(accessToken!, issuer);\n if (valid) return NextResponse.next();\n }\n\n if (!refreshToken) {\n return NextResponse.redirect(signInUrl);\n }\n\n const clientSecret = env(\"GEEKAPPS_AUTH_CLIENT_SECRET\") ?? \"\";\n const basicAuth = btoa(`${clientId ?? \"\"}:${clientSecret}`);\n\n let newAccessToken: string | null = null;\n let newRefreshToken: string | null = null;\n\n for (let attempt = 1; attempt <= MAX_REFRESH_ATTEMPTS; attempt++) {\n try {\n const refreshResponse = await fetch(`${issuer}/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/x-www-form-urlencoded\",\n authorization: `Basic ${basicAuth}`,\n },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n }),\n cache: \"no-store\",\n });\n\n if (!refreshResponse.ok) break;\n\n const data = (await refreshResponse.json()) as TokenLikeResponse;\n newAccessToken = data.accessToken ?? data.access_token ?? null;\n newRefreshToken = data.refreshToken ?? data.refresh_token ?? null;\n if (newAccessToken) break;\n } catch {\n if (attempt === MAX_REFRESH_ATTEMPTS) break;\n }\n }\n\n if (!newAccessToken) {\n // Refresh failed — clear the active slot and redirect to sign-in\n const response = NextResponse.redirect(signInUrl);\n const clearOpts = {\n httpOnly: true,\n secure: input.secureCookies ?? process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n maxAge: 0,\n };\n response.cookies.set(slotAt(activeIdx), \"\", clearOpts);\n response.cookies.set(slotRt(activeIdx), \"\", clearOpts);\n response.cookies.set(`${prefix}_m${activeIdx}`, \"\", clearOpts);\n response.cookies.set(tokenPubCookie, \"\", { ...clearOpts, httpOnly: false });\n response.cookies.set(activeCookie, \"0\", clearOpts);\n return response;\n }\n\n const cookieOptions = {\n httpOnly: true,\n secure: input.secureCookies ?? process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n maxAge: 60 * 60 * 24 * 30,\n ...(input.cookieDomain ? { domain: input.cookieDomain } : {}),\n };\n\n // Forward new token via request header so server actions in the same\n // request can read it — response cookies are not visible within the same request.\n const requestHeaders = new Headers(request.headers);\n requestHeaders.set(\"x-gk-access-token\", newAccessToken);\n\n const response = NextResponse.next({ request: { headers: requestHeaders } });\n response.cookies.set(slotAt(activeIdx), newAccessToken, cookieOptions);\n if (newRefreshToken) response.cookies.set(slotRt(activeIdx), newRefreshToken, cookieOptions);\n // Clear legacy _tp cookie to reduce header size\n if (request.cookies.get(tokenPubCookie)?.value) {\n response.cookies.set(tokenPubCookie, \"\", { httpOnly: false, maxAge: 0, path: \"/\" });\n }\n\n return response;\n };\n}\n"],"mappings":"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","names":["response"]}
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "name": "@geekapps/auth-nextjs",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {
7
7
  "./server": {
8
- "types": "./src/server.ts",
9
- "import": "./src/server.ts"
8
+ "types": "./dist/server.d.ts",
9
+ "import": "./dist/server.js"
10
10
  },
11
11
  "./client": {
12
- "types": "./src/client.tsx",
13
- "import": "./src/client.tsx"
12
+ "types": "./dist/client.d.ts",
13
+ "import": "./dist/client.js"
14
14
  },
15
15
  "./middleware": {
16
- "types": "./src/middleware.ts",
17
- "import": "./src/middleware.ts"
16
+ "types": "./dist/middleware.d.ts",
17
+ "import": "./dist/middleware.js"
18
18
  },
19
19
  "./actions": {
20
- "types": "./src/actions.ts",
21
- "import": "./src/actions.ts"
20
+ "types": "./dist/actions.d.ts",
21
+ "import": "./dist/actions.js"
22
22
  }
23
23
  },
24
24
  "files": [