@intelligo-dev/auth 1.0.0-beta.1

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.
Files changed (65) hide show
  1. package/LICENSE +201 -0
  2. package/dist/client.js +25 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/edge.js +39 -0
  5. package/dist/edge.js.map +1 -0
  6. package/dist/helpers.js +248 -0
  7. package/dist/helpers.js.map +1 -0
  8. package/dist/impersonation.js +42 -0
  9. package/dist/impersonation.js.map +1 -0
  10. package/dist/index.js +30 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/onboarding/errors.js +31 -0
  13. package/dist/onboarding/errors.js.map +1 -0
  14. package/dist/onboarding/schemas.js +24 -0
  15. package/dist/onboarding/schemas.js.map +1 -0
  16. package/dist/onboarding/service.js +147 -0
  17. package/dist/onboarding/service.js.map +1 -0
  18. package/dist/org-api.js +86 -0
  19. package/dist/org-api.js.map +1 -0
  20. package/dist/profile/errors.js +32 -0
  21. package/dist/profile/errors.js.map +1 -0
  22. package/dist/profile/schemas.js +20 -0
  23. package/dist/profile/schemas.js.map +1 -0
  24. package/dist/profile/service.js +157 -0
  25. package/dist/profile/service.js.map +1 -0
  26. package/dist/roles.js +17 -0
  27. package/dist/roles.js.map +1 -0
  28. package/dist/server.js +251 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/team/errors.js +31 -0
  31. package/dist/team/errors.js.map +1 -0
  32. package/dist/team/schemas.js +29 -0
  33. package/dist/team/schemas.js.map +1 -0
  34. package/dist/team/service.js +438 -0
  35. package/dist/team/service.js.map +1 -0
  36. package/dist/workspace/errors.js +32 -0
  37. package/dist/workspace/errors.js.map +1 -0
  38. package/dist/workspace/schemas.js +45 -0
  39. package/dist/workspace/schemas.js.map +1 -0
  40. package/dist/workspace/service.js +268 -0
  41. package/dist/workspace/service.js.map +1 -0
  42. package/dist/workspace-init.js +121 -0
  43. package/dist/workspace-init.js.map +1 -0
  44. package/package.json +58 -0
  45. package/src/client.ts +27 -0
  46. package/src/edge.ts +43 -0
  47. package/src/helpers.ts +317 -0
  48. package/src/impersonation.ts +57 -0
  49. package/src/index.ts +109 -0
  50. package/src/onboarding/errors.ts +52 -0
  51. package/src/onboarding/schemas.ts +27 -0
  52. package/src/onboarding/service.ts +174 -0
  53. package/src/org-api.ts +198 -0
  54. package/src/profile/errors.ts +58 -0
  55. package/src/profile/schemas.ts +23 -0
  56. package/src/profile/service.ts +208 -0
  57. package/src/roles.ts +17 -0
  58. package/src/server.ts +305 -0
  59. package/src/team/errors.ts +71 -0
  60. package/src/team/schemas.ts +35 -0
  61. package/src/team/service.ts +611 -0
  62. package/src/workspace/errors.ts +69 -0
  63. package/src/workspace/schemas.ts +57 -0
  64. package/src/workspace/service.ts +381 -0
  65. package/src/workspace-init.ts +140 -0
package/dist/server.js ADDED
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Better-Auth Server Configuration
3
+ *
4
+ * Configures authentication with:
5
+ * - Email + password authentication
6
+ * - OAuth providers (Google, GitHub) with graceful env var fallback
7
+ * - Drizzle database adapter
8
+ * - Session persistence (7-day expiration, 1-day update age)
9
+ * - Organization plugin for multi-tenant workspace support (Phase 10)
10
+ * - Email sending via Resend for verification, password reset, welcome (Phase 14)
11
+ */
12
+ import { betterAuth } from "better-auth";
13
+ import { drizzleAdapter } from "better-auth/adapters/drizzle";
14
+ import { admin, organization } from "better-auth/plugins";
15
+ import { createAccessControl } from "better-auth/plugins/access";
16
+ import { adminAc, defaultStatements, userAc, } from "better-auth/plugins/admin/access";
17
+ import { PLATFORM_ADMIN_ROLE } from "./roles";
18
+ /**
19
+ * Access control for the platform role.
20
+ *
21
+ * Better-Auth refuses an `adminRoles` entry that no role definition
22
+ * backs — "Invalid admin roles" at build time — which is the right
23
+ * behaviour: it stops a typo from silently granting nothing, or a
24
+ * renamed role from silently granting everything. `platform-admin`
25
+ * takes the plugin's own admin statements unchanged; the product
26
+ * defines no extra platform permissions yet.
27
+ */
28
+ const accessControl = createAccessControl(defaultStatements);
29
+ const platformAdminRole = accessControl.newRole(adminAc.statements);
30
+ const userRole = accessControl.newRole(userAc.statements);
31
+ import { db } from "@intelligo-dev/core/db";
32
+ import { users, sessions, accounts, verifications, organization as organizationTable, member, invitation, } from "@intelligo-dev/core/db/schema";
33
+ import { sendVerifyEmail, sendPasswordResetEmail, sendWelcomeEmail, sendInvitationEmail, } from "@intelligo-dev/core/email";
34
+ import { eq } from "drizzle-orm";
35
+ export const auth = betterAuth({
36
+ database: drizzleAdapter(db, {
37
+ provider: "pg",
38
+ // Map our schema tables to Better-Auth's expected names
39
+ schema: {
40
+ user: users,
41
+ session: sessions,
42
+ account: accounts,
43
+ verification: verifications,
44
+ // Organization plugin tables (Phase 10)
45
+ organization: organizationTable,
46
+ member: member,
47
+ invitation: invitation,
48
+ },
49
+ }),
50
+ baseURL: process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000",
51
+ emailAndPassword: {
52
+ enabled: true,
53
+ // Only enforce email verification when a real email provider is configured
54
+ // or in production — otherwise dev users (no RESEND_API_KEY) cannot log in.
55
+ requireEmailVerification: process.env.NODE_ENV === "production" || !!process.env.RESEND_API_KEY,
56
+ // Password reset email hook (EMAIL-05)
57
+ sendResetPassword: async ({ user, url }) => {
58
+ sendPasswordResetEmail({
59
+ to: user.email,
60
+ userName: user.name || user.email,
61
+ resetUrl: url,
62
+ }).catch((err) => console.error("[Auth] Failed to send password reset email:", err));
63
+ },
64
+ },
65
+ // Email verification hook (EMAIL-04)
66
+ emailVerification: {
67
+ sendVerificationEmail: async ({ user, url }) => {
68
+ sendVerifyEmail({
69
+ to: user.email,
70
+ userName: user.name || user.email,
71
+ verificationUrl: url,
72
+ }).catch((err) => console.error("[Auth] Failed to send verification email:", err));
73
+ },
74
+ sendOnSignUp: true,
75
+ autoSignInAfterVerification: true,
76
+ },
77
+ socialProviders: {
78
+ // Google OAuth - only enabled when env vars are configured
79
+ ...(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET
80
+ ? {
81
+ google: {
82
+ clientId: process.env.GOOGLE_CLIENT_ID,
83
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
84
+ },
85
+ }
86
+ : {}),
87
+ // GitHub OAuth - only enabled when env vars are configured
88
+ ...(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET
89
+ ? {
90
+ github: {
91
+ clientId: process.env.GITHUB_CLIENT_ID,
92
+ clientSecret: process.env.GITHUB_CLIENT_SECRET,
93
+ },
94
+ }
95
+ : {}),
96
+ },
97
+ session: {
98
+ // Sessions expire after 7 days
99
+ expiresIn: 60 * 60 * 24 * 7,
100
+ // Session token updated every 24 hours (extends expiration on active usage)
101
+ updateAge: 60 * 60 * 24,
102
+ },
103
+ trustedOrigins: [process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000"],
104
+ // Database hooks for automatic workspace setup (WORK-01)
105
+ databaseHooks: {
106
+ user: {
107
+ create: {
108
+ after: async (user) => {
109
+ // Auto-create personal workspace for new users
110
+ try {
111
+ const slug = ((user.email || "user").split("@")[0] || "user")
112
+ .toLowerCase()
113
+ .replace(/[^a-z0-9-]/g, "-")
114
+ .slice(0, 30);
115
+ await auth.api.createOrganization({
116
+ headers: new Headers(),
117
+ body: {
118
+ name: `${user.name || "User"}'s Workspace`,
119
+ slug: `${slug}-${Date.now().toString(36)}`,
120
+ userId: user.id, // Associate with the user
121
+ },
122
+ });
123
+ }
124
+ catch (error) {
125
+ // TR-0024: handle race — if hook fires twice for same signup (two
126
+ // concurrent requests), the unique slug constraint catches the dup.
127
+ // Check if an org was created despite the error.
128
+ if (error instanceof Error &&
129
+ (error.message?.includes("duplicate") ||
130
+ error.message?.includes("unique") ||
131
+ error.message?.includes("slug"))) {
132
+ const orgs = await auth.api.listOrganizations({
133
+ headers: new Headers(),
134
+ });
135
+ if (orgs && orgs.length > 0) {
136
+ // Org already created by the other hook — not an error.
137
+ return;
138
+ }
139
+ }
140
+ // Log for ops visibility; do not throw (user registration succeeded)
141
+ console.error("[user.create hook] Failed to create workspace:", error);
142
+ }
143
+ // Send welcome email (EMAIL-03, fire-and-forget).
144
+ // NOTE(DB-12): No retry or outbox — downstream failures silently ignored.
145
+ // Acceptable for v0.2; consider transactional outbox for Phase 14.
146
+ const dashboardUrl = `${process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000"}/dashboard`;
147
+ sendWelcomeEmail({
148
+ to: user.email,
149
+ userName: user.name || user.email,
150
+ dashboardUrl,
151
+ }).catch((err) => console.error("[Auth] Failed to send welcome email:", err));
152
+ },
153
+ },
154
+ },
155
+ session: {
156
+ create: {
157
+ before: async (session) => {
158
+ // Check if user is soft-deleted before creating session
159
+ try {
160
+ const userRecord = await db
161
+ .select({ deletedAt: users.deletedAt })
162
+ .from(users)
163
+ .where(eq(users.id, session.userId))
164
+ .limit(1);
165
+ if (userRecord[0]?.deletedAt) {
166
+ throw new Error("This account has been deleted. Contact support@intelligo.dev to recover your account within 30 days.");
167
+ }
168
+ }
169
+ catch (error) {
170
+ console.error("[session.create hook] Deleted user check failed:", error);
171
+ throw error; // Re-throw to prevent session creation
172
+ }
173
+ // Auto-set active organization on session creation
174
+ // NOTE(DB-11): Uses new Headers() — bypasses any future middleware
175
+ // (bot detection, request signing). Acceptable for v0.2; pass request
176
+ // headers through hook context if middleware layering is needed later.
177
+ try {
178
+ const orgs = await auth.api.listOrganizations({
179
+ headers: new Headers(),
180
+ query: { userId: session.userId },
181
+ });
182
+ if (orgs && orgs.length > 0) {
183
+ // Auto-set active org on session creation
184
+ return {
185
+ data: {
186
+ ...session,
187
+ activeOrganizationId: orgs[0].id,
188
+ },
189
+ };
190
+ }
191
+ }
192
+ catch (error) {
193
+ console.error("[session.create hook] Failed to set active org:", error);
194
+ }
195
+ return { data: session };
196
+ },
197
+ },
198
+ },
199
+ },
200
+ plugins: [
201
+ organization({
202
+ // Allow all users to create organizations (will be plan-gated in Phase 15)
203
+ allowUserToCreateOrganization: async () => true,
204
+ // Generous default limit (will be plan-gated later)
205
+ organizationLimit: 5,
206
+ // Creator becomes owner (explicit for clarity)
207
+ creatorRole: "owner",
208
+ // Invitation email sending via Resend (EMAIL-06, replaces Phase 10 placeholder)
209
+ sendInvitationEmail: async (data) => {
210
+ const appUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000";
211
+ sendInvitationEmail({
212
+ to: data.email,
213
+ inviterName: data.inviter?.user?.name || "A team member",
214
+ workspaceName: data.organization?.name || "a workspace",
215
+ role: data.role || "member",
216
+ acceptUrl: `${appUrl}/accept-invitation/${data.id}`,
217
+ declineUrl: `${appUrl}/invitation/decline?id=${data.id}`,
218
+ }).catch((err) => console.error("[Auth] Failed to send invitation email:", err));
219
+ },
220
+ // Invitations expire after 7 days (matches TEAM-10)
221
+ invitationExpiresIn: 60 * 60 * 24 * 7,
222
+ }),
223
+ /**
224
+ * Platform administration — enabled only for its impersonation
225
+ * endpoints, which the operational console uses for support.
226
+ *
227
+ * `adminRoles` is deliberately a platform role and not a workspace
228
+ * one: workspace `owner` is per-tenant and every self-serve signup
229
+ * owns their own workspace, so gating anything cross-tenant on it
230
+ * grants it to everybody. `users.role` carries the platform role;
231
+ * requirePlatformAdmin promotes from PLATFORM_ADMIN_EMAILS into it.
232
+ *
233
+ * An impersonation session is capped at 30 minutes. Support work
234
+ * is measured in minutes, and a session inherited by whoever next
235
+ * uses that browser is the failure mode worth designing against.
236
+ *
237
+ * `allowImpersonatingAdmins` stays false: one platform admin
238
+ * cannot take over another's account, which is what keeps the
239
+ * audit trail meaningful.
240
+ */
241
+ admin({
242
+ ac: accessControl,
243
+ roles: { user: userRole, [PLATFORM_ADMIN_ROLE]: platformAdminRole },
244
+ defaultRole: "user",
245
+ adminRoles: [PLATFORM_ADMIN_ROLE],
246
+ impersonationSessionDuration: 30 * 60,
247
+ allowImpersonatingAdmins: false,
248
+ }),
249
+ ],
250
+ });
251
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Team service error type.
3
+ *
4
+ * The team service (./service.ts) throws this for every failure it
5
+ * recognizes rather than returning an ad-hoc `{ success, error }`
6
+ * envelope — that shaping is a transport concern (a Server Action, a
7
+ * route handler) and belongs one layer up, alongside
8
+ * revalidatePath/Sentry/toast/i18n, none of which this package may
9
+ * depend on.
10
+ */
11
+ export class TeamServiceError extends Error {
12
+ constructor(code, message, options) {
13
+ super(message);
14
+ this.name = "TeamServiceError";
15
+ this.code = code;
16
+ this.meta = options?.meta;
17
+ if (options?.cause !== undefined) {
18
+ // ES2020 target predates the standard `cause` constructor option;
19
+ // assign it directly so `instanceof Error` consumers (and Node's
20
+ // own error inspection) still see it.
21
+ this.cause = options.cause;
22
+ }
23
+ // Restore prototype chain (extending built-ins across some
24
+ // transpilation targets loses `instanceof`).
25
+ Object.setPrototypeOf(this, TeamServiceError.prototype);
26
+ }
27
+ }
28
+ export function isTeamServiceError(error) {
29
+ return error instanceof TeamServiceError;
30
+ }
31
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/team/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiCH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAIzC,YACE,IAA0B,EAC1B,OAAe,EACf,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,kEAAkE;YAClE,iEAAiE;YACjE,sCAAsC;YACrC,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,2DAA2D;QAC3D,6CAA6C;QAC7C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,KAAK,YAAY,gBAAgB,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Team Management Validation Schemas
3
+ *
4
+ * Zod schemas for team invite and member management inputs, shared by
5
+ * the team service and its transports.
6
+ *
7
+ * (Ported from the product application’s team validation module — same
8
+ * semantics. Ignite's copy is retired at cutover.)
9
+ */
10
+ import { z } from "zod";
11
+ /**
12
+ * Invite Member Schema
13
+ * Email + role for inviting new team members
14
+ */
15
+ export const inviteMemberSchema = z.object({
16
+ email: z.string().email("Please enter a valid email address"),
17
+ role: z.enum(["admin", "member"], {
18
+ required_error: "Please select a role",
19
+ }),
20
+ });
21
+ /**
22
+ * Update Role Schema
23
+ * For changing an existing member's role
24
+ */
25
+ export const updateRoleSchema = z.object({
26
+ memberId: z.string().min(1),
27
+ role: z.enum(["admin", "member"]),
28
+ });
29
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/team/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,oCAAoC,CAAC;IAC7D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE;QAChC,cAAc,EAAE,sBAAsB;KACvC,CAAC;CACH,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;CAClC,CAAC,CAAC"}