@checkstack/auth-backend 0.1.0 → 0.2.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.
- package/CHANGELOG.md +103 -0
- package/drizzle/0004_lucky_power_man.sql +21 -0
- package/drizzle/meta/0004_snapshot.json +1050 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/src/index.ts +166 -162
- package/src/router.test.ts +11 -11
- package/src/router.ts +98 -98
- package/src/schema.ts +20 -20
- package/src/teams.test.ts +836 -81
- package/src/utils/user.test.ts +10 -10
- package/src/utils/user.ts +13 -13
package/src/utils/user.test.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { User } from "better-auth/types";
|
|
|
5
5
|
// Mock Drizzle DB
|
|
6
6
|
const createMockDb = (data: {
|
|
7
7
|
roles?: unknown[];
|
|
8
|
-
|
|
8
|
+
accessRules?: unknown[];
|
|
9
9
|
teams?: unknown[];
|
|
10
10
|
}) => {
|
|
11
11
|
const mockDb: unknown = {
|
|
@@ -16,7 +16,7 @@ const createMockDb = (data: {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
// Track call count for sequential responses
|
|
19
|
-
// Call order in enrichUser: 1=roles, 2+=
|
|
19
|
+
// Call order in enrichUser: 1=roles, 2+=access rules per role, final=teams
|
|
20
20
|
let callCount = 0;
|
|
21
21
|
const nonAdminRoles = (data.roles || []).filter(
|
|
22
22
|
(r) => (r as { roleId: string }).roleId !== "admin"
|
|
@@ -30,8 +30,8 @@ const createMockDb = (data: {
|
|
|
30
30
|
return resolve(data.roles || []);
|
|
31
31
|
}
|
|
32
32
|
if (callCount <= 1 + nonAdminRoles.length && nonAdminRoles.length > 0) {
|
|
33
|
-
//
|
|
34
|
-
return resolve(data.
|
|
33
|
+
// Access rule calls for each non-admin role
|
|
34
|
+
return resolve(data.accessRules || []);
|
|
35
35
|
}
|
|
36
36
|
// Team memberships (final call)
|
|
37
37
|
return resolve(data.teams || []);
|
|
@@ -50,7 +50,7 @@ describe("enrichUser", () => {
|
|
|
50
50
|
updatedAt: new Date(),
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
it("should enrich user with admin role and wildcard
|
|
53
|
+
it("should enrich user with admin role and wildcard access", async () => {
|
|
54
54
|
const mockDb = createMockDb({
|
|
55
55
|
roles: [{ roleId: "admin" }],
|
|
56
56
|
teams: [{ teamId: "team-1" }],
|
|
@@ -62,14 +62,14 @@ describe("enrichUser", () => {
|
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
expect(result.roles).toContain("admin");
|
|
65
|
-
expect(result.
|
|
65
|
+
expect(result.accessRules).toContain("*");
|
|
66
66
|
expect(result.teamIds).toEqual(["team-1"]);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
it("should enrich user with custom roles and
|
|
69
|
+
it("should enrich user with custom roles and access rules", async () => {
|
|
70
70
|
const mockDb = createMockDb({
|
|
71
71
|
roles: [{ roleId: "editor" }],
|
|
72
|
-
|
|
72
|
+
accessRules: [{ accessRuleId: "blog.edit" }],
|
|
73
73
|
teams: [],
|
|
74
74
|
});
|
|
75
75
|
|
|
@@ -79,7 +79,7 @@ describe("enrichUser", () => {
|
|
|
79
79
|
);
|
|
80
80
|
|
|
81
81
|
expect(result.roles).toContain("editor");
|
|
82
|
-
expect(result.
|
|
82
|
+
expect(result.accessRules).toContain("blog.edit");
|
|
83
83
|
expect(result.teamIds).toEqual([]);
|
|
84
84
|
});
|
|
85
85
|
|
|
@@ -95,7 +95,7 @@ describe("enrichUser", () => {
|
|
|
95
95
|
);
|
|
96
96
|
|
|
97
97
|
expect(result.roles).toEqual([]);
|
|
98
|
-
expect(result.
|
|
98
|
+
expect(result.accessRules).toEqual([]);
|
|
99
99
|
expect(result.teamIds).toEqual([]);
|
|
100
100
|
});
|
|
101
101
|
|
package/src/utils/user.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { RealUser } from "@checkstack/backend-api";
|
|
|
5
5
|
import * as schema from "../schema";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Enriches a better-auth User with roles,
|
|
8
|
+
* Enriches a better-auth User with roles, access rules, and team memberships from the database.
|
|
9
9
|
* Returns a RealUser type for use in the RPC context.
|
|
10
10
|
*/
|
|
11
11
|
export const enrichUser = async (
|
|
@@ -23,28 +23,28 @@ export const enrichUser = async (
|
|
|
23
23
|
.where(eq(schema.userRole.userId, user.id));
|
|
24
24
|
|
|
25
25
|
const roles = userRoles.map((r) => r.roleId);
|
|
26
|
-
const
|
|
26
|
+
const accessRulesSet = new Set<string>();
|
|
27
27
|
|
|
28
|
-
// 2. Get
|
|
28
|
+
// 2. Get access rules for each role
|
|
29
29
|
for (const roleId of roles) {
|
|
30
30
|
if (roleId === "admin") {
|
|
31
|
-
|
|
31
|
+
accessRulesSet.add("*");
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const
|
|
35
|
+
const roleAccessRules = await db
|
|
36
36
|
.select({
|
|
37
|
-
|
|
37
|
+
accessRuleId: schema.accessRule.id,
|
|
38
38
|
})
|
|
39
|
-
.from(schema.
|
|
39
|
+
.from(schema.roleAccessRule)
|
|
40
40
|
.innerJoin(
|
|
41
|
-
schema.
|
|
42
|
-
eq(schema.
|
|
41
|
+
schema.accessRule,
|
|
42
|
+
eq(schema.accessRule.id, schema.roleAccessRule.accessRuleId)
|
|
43
43
|
)
|
|
44
|
-
.where(eq(schema.
|
|
44
|
+
.where(eq(schema.roleAccessRule.roleId, roleId));
|
|
45
45
|
|
|
46
|
-
for (const p of
|
|
47
|
-
|
|
46
|
+
for (const p of roleAccessRules) {
|
|
47
|
+
accessRulesSet.add(p.accessRuleId);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -64,7 +64,7 @@ export const enrichUser = async (
|
|
|
64
64
|
email: user.email,
|
|
65
65
|
name: user.name,
|
|
66
66
|
roles,
|
|
67
|
-
|
|
67
|
+
accessRules: [...accessRulesSet],
|
|
68
68
|
teamIds,
|
|
69
69
|
};
|
|
70
70
|
};
|