@stacksjs/auth 0.70.88 → 0.70.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authentication.d.ts +43 -0
- package/dist/authentication.js +413 -0
- package/dist/authenticator.d.ts +17 -0
- package/dist/authenticator.js +14 -0
- package/dist/authorizable.d.ts +77 -0
- package/dist/authorizable.js +28 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.js +26 -0
- package/dist/email-verification.d.ts +29 -0
- package/dist/email-verification.js +111 -0
- package/dist/gate.d.ts +180 -0
- package/dist/gate.js +203 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +26 -0
- package/dist/internal-constants.d.ts +19 -0
- package/dist/internal-constants.js +1 -0
- package/dist/middleware.d.ts +14 -0
- package/dist/middleware.js +28 -0
- package/dist/passkey.d.ts +97 -0
- package/dist/passkey.js +76 -0
- package/dist/password/reset.d.ts +10 -0
- package/dist/password/reset.js +156 -0
- package/dist/policy.d.ts +33 -0
- package/dist/policy.js +91 -0
- package/dist/rate-limiter.d.ts +44 -0
- package/dist/rate-limiter.js +91 -0
- package/dist/rbac-seed.d.ts +24 -0
- package/dist/rbac-seed.js +30 -0
- package/dist/rbac-store-bqb.d.ts +18 -0
- package/dist/rbac-store-bqb.js +180 -0
- package/dist/rbac.d.ts +265 -0
- package/dist/rbac.js +324 -0
- package/dist/register.d.ts +3 -0
- package/dist/register.js +43 -0
- package/dist/session-auth.d.ts +67 -0
- package/dist/session-auth.js +151 -0
- package/dist/team.d.ts +121 -0
- package/dist/team.js +88 -0
- package/dist/token.d.ts +16 -0
- package/dist/token.js +21 -0
- package/dist/tokens.d.ts +284 -0
- package/dist/tokens.js +489 -0
- package/dist/two-factor.d.ts +67 -0
- package/dist/two-factor.js +113 -0
- package/dist/user.d.ts +34 -0
- package/dist/user.js +41 -0
- package/package.json +3 -3
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isUniqueViolation } from '@stacksjs/orm';
|
|
2
|
+
import type { PermissionRecord, RbacStore, RoleRecord } from './rbac';
|
|
3
|
+
/**
|
|
4
|
+
* Swallow unique-constraint violations. Anything else is re-thrown so a
|
|
5
|
+
* "connection lost" mid-INSERT doesn't get silently treated as
|
|
6
|
+
* "already assigned".
|
|
7
|
+
*
|
|
8
|
+
* Exported for direct unit testing — the live pivot helpers below also use it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function swallowDuplicate(err: unknown): void;
|
|
11
|
+
/**
|
|
12
|
+
* Map a raw DB row to a typed record. Both `roles` and `permissions` share
|
|
13
|
+
* the same shape, so one mapper covers both — the call site provides the
|
|
14
|
+
* generic. Exported for unit testing.
|
|
15
|
+
*/
|
|
16
|
+
export declare function toRecord<T extends RoleRecord | PermissionRecord>(row: Record<string, unknown> | undefined): T | null;
|
|
17
|
+
export declare function createBqbRbacStore(): RbacStore;
|
|
18
|
+
export { isUniqueViolation };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { db } from "@stacksjs/database";
|
|
2
|
+
import { isUniqueViolation } from "@stacksjs/orm";
|
|
3
|
+
|
|
4
|
+
export { isUniqueViolation };
|
|
5
|
+
export function swallowDuplicate(err) {
|
|
6
|
+
if (!isUniqueViolation(err))
|
|
7
|
+
throw err;
|
|
8
|
+
}
|
|
9
|
+
export function toRecord(row) {
|
|
10
|
+
if (!row)
|
|
11
|
+
return null;
|
|
12
|
+
return {
|
|
13
|
+
id: Number(row.id),
|
|
14
|
+
name: String(row.name),
|
|
15
|
+
guard_name: String(row.guard_name),
|
|
16
|
+
description: row.description == null ? void 0 : String(row.description),
|
|
17
|
+
created_at: row.created_at == null ? void 0 : String(row.created_at),
|
|
18
|
+
updated_at: row.updated_at == null ? void 0 : String(row.updated_at)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async function insertAndFetch(table, name, guardName, description) {
|
|
22
|
+
await db.insertInto(table).values({ name, guard_name: guardName, description: description ?? null }).execute();
|
|
23
|
+
const row = await db.selectFrom(table).selectAll().where("name", "=", name).where("guard_name", "=", guardName).orderBy("id", "desc").limit(1).executeTakeFirst(), rec = toRecord(row);
|
|
24
|
+
if (!rec)
|
|
25
|
+
throw Error(`[rbac] insertAndFetch(${table}, ${name}, ${guardName}) succeeded but follow-up SELECT returned nothing`);
|
|
26
|
+
return rec;
|
|
27
|
+
}
|
|
28
|
+
async function pivotAttach(table, cols) {
|
|
29
|
+
let q = db.selectFrom(table).select("user_id" in cols ? "user_id" : "role_id");
|
|
30
|
+
for (const [k, v] of Object.entries(cols))
|
|
31
|
+
q = q.where(k, "=", v);
|
|
32
|
+
if (await q.limit(1).executeTakeFirst())
|
|
33
|
+
return;
|
|
34
|
+
try {
|
|
35
|
+
await db.insertInto(table).values(cols).execute();
|
|
36
|
+
} catch (err) {
|
|
37
|
+
swallowDuplicate(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function pivotDetach(table, cols) {
|
|
41
|
+
let q = db.deleteFrom(table);
|
|
42
|
+
for (const [k, v] of Object.entries(cols))
|
|
43
|
+
q = q.where(k, "=", v);
|
|
44
|
+
await q.execute();
|
|
45
|
+
}
|
|
46
|
+
async function pivotDetachAll(table, column, value) {
|
|
47
|
+
await db.deleteFrom(table).where(column, "=", value).execute();
|
|
48
|
+
}
|
|
49
|
+
async function pivotSync(table, ownerColumn, ownerId, targetColumn, targetIds) {
|
|
50
|
+
const unique = Array.from(new Set(targetIds));
|
|
51
|
+
await db.transaction(async (rawTrx) => {
|
|
52
|
+
const trx = rawTrx;
|
|
53
|
+
await trx.deleteFrom(table).where(ownerColumn, "=", ownerId).execute();
|
|
54
|
+
if (unique.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
const rows = unique.map((id) => ({ [ownerColumn]: ownerId, [targetColumn]: id }));
|
|
57
|
+
try {
|
|
58
|
+
await trx.insertInto(table).values(rows).execute();
|
|
59
|
+
} catch (err) {
|
|
60
|
+
swallowDuplicate(err);
|
|
61
|
+
for (const id of unique)
|
|
62
|
+
try {
|
|
63
|
+
await trx.insertInto(table).values({ [ownerColumn]: ownerId, [targetColumn]: id }).execute();
|
|
64
|
+
} catch (innerErr) {
|
|
65
|
+
swallowDuplicate(innerErr);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
export function createBqbRbacStore() {
|
|
71
|
+
return {
|
|
72
|
+
async findRoleByName(name, guardName = "web") {
|
|
73
|
+
const row = await db.selectFrom("roles").selectAll().where("name", "=", name).where("guard_name", "=", guardName).limit(1).executeTakeFirst();
|
|
74
|
+
return toRecord(row);
|
|
75
|
+
},
|
|
76
|
+
async findRoleById(id) {
|
|
77
|
+
const row = await db.selectFrom("roles").selectAll().where("id", "=", id).limit(1).executeTakeFirst();
|
|
78
|
+
return toRecord(row);
|
|
79
|
+
},
|
|
80
|
+
async createRole(name, guardName = "web", description) {
|
|
81
|
+
return await insertAndFetch("roles", name, guardName, description);
|
|
82
|
+
},
|
|
83
|
+
async deleteRole(id) {
|
|
84
|
+
await db.deleteFrom("user_roles").where("role_id", "=", id).execute();
|
|
85
|
+
await db.deleteFrom("role_permissions").where("role_id", "=", id).execute();
|
|
86
|
+
await db.deleteFrom("roles").where("id", "=", id).execute();
|
|
87
|
+
},
|
|
88
|
+
async getAllRoles(guardName) {
|
|
89
|
+
let q = db.selectFrom("roles").selectAll();
|
|
90
|
+
if (guardName)
|
|
91
|
+
q = q.where("guard_name", "=", guardName);
|
|
92
|
+
return (await q.orderBy("id", "asc").execute()).map((r) => toRecord(r)).filter(Boolean);
|
|
93
|
+
},
|
|
94
|
+
async findPermissionByName(name, guardName = "web") {
|
|
95
|
+
const row = await db.selectFrom("permissions").selectAll().where("name", "=", name).where("guard_name", "=", guardName).limit(1).executeTakeFirst();
|
|
96
|
+
return toRecord(row);
|
|
97
|
+
},
|
|
98
|
+
async findPermissionById(id) {
|
|
99
|
+
const row = await db.selectFrom("permissions").selectAll().where("id", "=", id).limit(1).executeTakeFirst();
|
|
100
|
+
return toRecord(row);
|
|
101
|
+
},
|
|
102
|
+
async createPermission(name, guardName = "web", description) {
|
|
103
|
+
return await insertAndFetch("permissions", name, guardName, description);
|
|
104
|
+
},
|
|
105
|
+
async deletePermission(id) {
|
|
106
|
+
await db.deleteFrom("user_permissions").where("permission_id", "=", id).execute();
|
|
107
|
+
await db.deleteFrom("role_permissions").where("permission_id", "=", id).execute();
|
|
108
|
+
await db.deleteFrom("permissions").where("id", "=", id).execute();
|
|
109
|
+
},
|
|
110
|
+
async getAllPermissions(guardName) {
|
|
111
|
+
let q = db.selectFrom("permissions").selectAll();
|
|
112
|
+
if (guardName)
|
|
113
|
+
q = q.where("guard_name", "=", guardName);
|
|
114
|
+
return (await q.orderBy("id", "asc").execute()).map((r) => toRecord(r)).filter(Boolean);
|
|
115
|
+
},
|
|
116
|
+
async getUserRoles(userId) {
|
|
117
|
+
return (await db.selectFrom("roles").innerJoin("user_roles", "user_roles.role_id", "=", "roles.id").select([
|
|
118
|
+
"roles.id as id",
|
|
119
|
+
"roles.name as name",
|
|
120
|
+
"roles.guard_name as guard_name",
|
|
121
|
+
"roles.description as description",
|
|
122
|
+
"roles.created_at as created_at",
|
|
123
|
+
"roles.updated_at as updated_at"
|
|
124
|
+
]).where("user_roles.user_id", "=", userId).orderBy("roles.id", "asc").execute()).map((r) => toRecord(r)).filter(Boolean);
|
|
125
|
+
},
|
|
126
|
+
assignRoleToUser(userId, roleId) {
|
|
127
|
+
return pivotAttach("user_roles", { user_id: userId, role_id: roleId });
|
|
128
|
+
},
|
|
129
|
+
removeRoleFromUser(userId, roleId) {
|
|
130
|
+
return pivotDetach("user_roles", { user_id: userId, role_id: roleId });
|
|
131
|
+
},
|
|
132
|
+
removeAllRolesFromUser(userId) {
|
|
133
|
+
return pivotDetachAll("user_roles", "user_id", userId);
|
|
134
|
+
},
|
|
135
|
+
syncUserRoles(userId, roleIds) {
|
|
136
|
+
return pivotSync("user_roles", "user_id", userId, "role_id", roleIds);
|
|
137
|
+
},
|
|
138
|
+
async getUserDirectPermissions(userId) {
|
|
139
|
+
return (await db.selectFrom("permissions").innerJoin("user_permissions", "user_permissions.permission_id", "=", "permissions.id").select([
|
|
140
|
+
"permissions.id as id",
|
|
141
|
+
"permissions.name as name",
|
|
142
|
+
"permissions.guard_name as guard_name",
|
|
143
|
+
"permissions.description as description",
|
|
144
|
+
"permissions.created_at as created_at",
|
|
145
|
+
"permissions.updated_at as updated_at"
|
|
146
|
+
]).where("user_permissions.user_id", "=", userId).orderBy("permissions.id", "asc").execute()).map((r) => toRecord(r)).filter(Boolean);
|
|
147
|
+
},
|
|
148
|
+
assignPermissionToUser(userId, permissionId) {
|
|
149
|
+
return pivotAttach("user_permissions", { user_id: userId, permission_id: permissionId });
|
|
150
|
+
},
|
|
151
|
+
removePermissionFromUser(userId, permissionId) {
|
|
152
|
+
return pivotDetach("user_permissions", { user_id: userId, permission_id: permissionId });
|
|
153
|
+
},
|
|
154
|
+
removeAllPermissionsFromUser(userId) {
|
|
155
|
+
return pivotDetachAll("user_permissions", "user_id", userId);
|
|
156
|
+
},
|
|
157
|
+
syncUserPermissions(userId, permissionIds) {
|
|
158
|
+
return pivotSync("user_permissions", "user_id", userId, "permission_id", permissionIds);
|
|
159
|
+
},
|
|
160
|
+
async getRolePermissions(roleId) {
|
|
161
|
+
return (await db.selectFrom("permissions").innerJoin("role_permissions", "role_permissions.permission_id", "=", "permissions.id").select([
|
|
162
|
+
"permissions.id as id",
|
|
163
|
+
"permissions.name as name",
|
|
164
|
+
"permissions.guard_name as guard_name",
|
|
165
|
+
"permissions.description as description",
|
|
166
|
+
"permissions.created_at as created_at",
|
|
167
|
+
"permissions.updated_at as updated_at"
|
|
168
|
+
]).where("role_permissions.role_id", "=", roleId).orderBy("permissions.id", "asc").execute()).map((r) => toRecord(r)).filter(Boolean);
|
|
169
|
+
},
|
|
170
|
+
assignPermissionToRole(roleId, permissionId) {
|
|
171
|
+
return pivotAttach("role_permissions", { role_id: roleId, permission_id: permissionId });
|
|
172
|
+
},
|
|
173
|
+
removePermissionFromRole(roleId, permissionId) {
|
|
174
|
+
return pivotDetach("role_permissions", { role_id: roleId, permission_id: permissionId });
|
|
175
|
+
},
|
|
176
|
+
syncRolePermissions(roleId, permissionIds) {
|
|
177
|
+
return pivotSync("role_permissions", "role_id", roleId, "permission_id", permissionIds);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
package/dist/rbac.d.ts
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import type { UserModel as OrmUserModel } from '@stacksjs/orm';
|
|
2
|
+
/**
|
|
3
|
+
* Set the RBAC store implementation
|
|
4
|
+
*/
|
|
5
|
+
export declare function setRbacStore(rbacStore: RbacStore): void;
|
|
6
|
+
/**
|
|
7
|
+
* Flush the RBAC cache
|
|
8
|
+
*/
|
|
9
|
+
export declare function flushRbacCache(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new role
|
|
12
|
+
*/
|
|
13
|
+
export declare function createRole(name: string, guardName?: string, description?: string): Promise<RoleRecord>;
|
|
14
|
+
/**
|
|
15
|
+
* Find a role by name
|
|
16
|
+
*/
|
|
17
|
+
export declare function findRole(name: string, guardName?: string): Promise<RoleRecord | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Delete a role
|
|
20
|
+
*/
|
|
21
|
+
export declare function deleteRole(name: string, guardName?: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Get all roles
|
|
24
|
+
*/
|
|
25
|
+
export declare function getAllRoles(guardName?: string): Promise<RoleRecord[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Create a new permission
|
|
28
|
+
*/
|
|
29
|
+
export declare function createPermission(name: string, guardName?: string, description?: string): Promise<PermissionRecord>;
|
|
30
|
+
/**
|
|
31
|
+
* Find a permission by name
|
|
32
|
+
*/
|
|
33
|
+
export declare function findPermission(name: string, guardName?: string): Promise<PermissionRecord | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Delete a permission
|
|
36
|
+
*/
|
|
37
|
+
export declare function deletePermission(name: string, guardName?: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Get all permissions
|
|
40
|
+
*/
|
|
41
|
+
export declare function getAllPermissions(guardName?: string): Promise<PermissionRecord[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Get all roles for a user
|
|
44
|
+
*/
|
|
45
|
+
export declare function getUserRoles(user: UserModel | { id: number } | number): Promise<RoleRecord[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Assign a role to a user
|
|
48
|
+
*/
|
|
49
|
+
export declare function assignRole(user: UserModel | { id: number } | number, roleName: string, guardName?: string): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Remove a role from a user
|
|
52
|
+
*/
|
|
53
|
+
export declare function removeRole(user: UserModel | { id: number } | number, roleName: string, guardName?: string): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Remove all roles from a user
|
|
56
|
+
*/
|
|
57
|
+
export declare function removeAllRoles(user: UserModel | { id: number } | number): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Sync roles for a user (replaces all current roles)
|
|
60
|
+
*/
|
|
61
|
+
export declare function syncRoles(user: UserModel | { id: number } | number, roleNames: string[], guardName?: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Check if a user has a specific role
|
|
64
|
+
*/
|
|
65
|
+
export declare function hasRole(user: UserModel | { id: number } | number, roleName: string, guardName?: string): Promise<boolean>;
|
|
66
|
+
/**
|
|
67
|
+
* Check if a user has any of the given roles
|
|
68
|
+
*/
|
|
69
|
+
export declare function hasAnyRole(user: UserModel | { id: number } | number, roleNames: string[], guardName?: string): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Check if a user has all of the given roles
|
|
72
|
+
*/
|
|
73
|
+
export declare function hasAllRoles(user: UserModel | { id: number } | number, roleNames: string[], guardName?: string): Promise<boolean>;
|
|
74
|
+
/**
|
|
75
|
+
* Get all permissions for a user (direct + via roles)
|
|
76
|
+
*/
|
|
77
|
+
export declare function getUserPermissions(user: UserModel | { id: number } | number): Promise<PermissionRecord[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Give a direct permission to a user
|
|
80
|
+
*/
|
|
81
|
+
export declare function givePermission(user: UserModel | { id: number } | number, permissionName: string, guardName?: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Revoke a direct permission from a user
|
|
84
|
+
*/
|
|
85
|
+
export declare function revokePermission(user: UserModel | { id: number } | number, permissionName: string, guardName?: string): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Revoke all direct permissions from a user
|
|
88
|
+
*/
|
|
89
|
+
export declare function revokeAllPermissions(user: UserModel | { id: number } | number): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Sync direct permissions for a user
|
|
92
|
+
*/
|
|
93
|
+
export declare function syncPermissions(user: UserModel | { id: number } | number, permissionNames: string[], guardName?: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Check if a user has a specific permission (direct or via role)
|
|
96
|
+
*/
|
|
97
|
+
export declare function hasPermission(user: UserModel | { id: number } | number, permissionName: string, guardName?: string): Promise<boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* Check if a user has any of the given permissions
|
|
100
|
+
*/
|
|
101
|
+
export declare function hasAnyPermission(user: UserModel | { id: number } | number, permissionNames: string[], guardName?: string): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Check if a user has all of the given permissions
|
|
104
|
+
*/
|
|
105
|
+
export declare function hasAllPermissions(user: UserModel | { id: number } | number, permissionNames: string[], guardName?: string): Promise<boolean>;
|
|
106
|
+
/**
|
|
107
|
+
* Get all permissions for a role
|
|
108
|
+
*/
|
|
109
|
+
export declare function getRolePermissions(roleId: number): Promise<PermissionRecord[]>;
|
|
110
|
+
/**
|
|
111
|
+
* Assign a permission to a role
|
|
112
|
+
*/
|
|
113
|
+
export declare function givePermissionToRole(roleName: string, permissionName: string, guardName?: string): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Remove a permission from a role
|
|
116
|
+
*/
|
|
117
|
+
export declare function revokePermissionFromRole(roleName: string, permissionName: string, guardName?: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Sync permissions for a role
|
|
120
|
+
*/
|
|
121
|
+
export declare function syncRolePermissions(roleName: string, permissionNames: string[], guardName?: string): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Add RBAC methods to a user object
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* const user = withRbac(authenticatedUser)
|
|
127
|
+
* if (await user.hasRole('admin')) { ... }
|
|
128
|
+
* await user.assignRole('editor')
|
|
129
|
+
*/
|
|
130
|
+
export declare function withRbac<T extends UserModel | { id: number }>(user: T): T & RbacMethods;
|
|
131
|
+
/**
|
|
132
|
+
* RBAC facade for convenient access
|
|
133
|
+
*/
|
|
134
|
+
export declare const Rbac: {
|
|
135
|
+
setStore: unknown;
|
|
136
|
+
flushCache: unknown;
|
|
137
|
+
createRole: typeof createRole;
|
|
138
|
+
findRole: typeof findRole;
|
|
139
|
+
deleteRole: typeof deleteRole;
|
|
140
|
+
getAllRoles: typeof getAllRoles;
|
|
141
|
+
createPermission: typeof createPermission;
|
|
142
|
+
findPermission: typeof findPermission;
|
|
143
|
+
deletePermission: typeof deletePermission;
|
|
144
|
+
getAllPermissions: typeof getAllPermissions;
|
|
145
|
+
getUserRoles: typeof getUserRoles;
|
|
146
|
+
assignRole: typeof assignRole;
|
|
147
|
+
removeRole: typeof removeRole;
|
|
148
|
+
removeAllRoles: typeof removeAllRoles;
|
|
149
|
+
syncRoles: typeof syncRoles;
|
|
150
|
+
hasRole: typeof hasRole;
|
|
151
|
+
hasAnyRole: typeof hasAnyRole;
|
|
152
|
+
hasAllRoles: typeof hasAllRoles;
|
|
153
|
+
getUserPermissions: typeof getUserPermissions;
|
|
154
|
+
givePermission: typeof givePermission;
|
|
155
|
+
revokePermission: typeof revokePermission;
|
|
156
|
+
revokeAllPermissions: typeof revokeAllPermissions;
|
|
157
|
+
syncPermissions: typeof syncPermissions;
|
|
158
|
+
hasPermission: typeof hasPermission;
|
|
159
|
+
hasAnyPermission: typeof hasAnyPermission;
|
|
160
|
+
hasAllPermissions: typeof hasAllPermissions;
|
|
161
|
+
getRolePermissions: typeof getRolePermissions;
|
|
162
|
+
givePermissionToRole: typeof givePermissionToRole;
|
|
163
|
+
revokePermissionFromRole: typeof revokePermissionFromRole;
|
|
164
|
+
syncRolePermissions: typeof syncRolePermissions;
|
|
165
|
+
withRbac: typeof withRbac
|
|
166
|
+
};
|
|
167
|
+
export declare interface RoleRecord {
|
|
168
|
+
id: number
|
|
169
|
+
name: string
|
|
170
|
+
guard_name: string
|
|
171
|
+
description?: string
|
|
172
|
+
created_at?: string
|
|
173
|
+
updated_at?: string
|
|
174
|
+
}
|
|
175
|
+
export declare interface PermissionRecord {
|
|
176
|
+
id: number
|
|
177
|
+
name: string
|
|
178
|
+
guard_name: string
|
|
179
|
+
description?: string
|
|
180
|
+
created_at?: string
|
|
181
|
+
updated_at?: string
|
|
182
|
+
}
|
|
183
|
+
export declare interface RolePermissionPivot {
|
|
184
|
+
role_id: number
|
|
185
|
+
permission_id: number
|
|
186
|
+
created_at?: string
|
|
187
|
+
}
|
|
188
|
+
export declare interface UserRolePivot {
|
|
189
|
+
user_id: number
|
|
190
|
+
role_id: number
|
|
191
|
+
created_at?: string
|
|
192
|
+
}
|
|
193
|
+
export declare interface UserPermissionPivot {
|
|
194
|
+
user_id: number
|
|
195
|
+
permission_id: number
|
|
196
|
+
created_at?: string
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* RBAC database adapter interface.
|
|
200
|
+
* Implement this to connect RBAC to your database layer.
|
|
201
|
+
*/
|
|
202
|
+
export declare interface RbacStore {
|
|
203
|
+
findRoleByName(name: string, guardName?: string): Promise<RoleRecord | null>
|
|
204
|
+
findRoleById(id: number): Promise<RoleRecord | null>
|
|
205
|
+
createRole(name: string, guardName?: string, description?: string): Promise<RoleRecord>
|
|
206
|
+
deleteRole(id: number): Promise<void>
|
|
207
|
+
getAllRoles(guardName?: string): Promise<RoleRecord[]>
|
|
208
|
+
findPermissionByName(name: string, guardName?: string): Promise<PermissionRecord | null>
|
|
209
|
+
findPermissionById(id: number): Promise<PermissionRecord | null>
|
|
210
|
+
createPermission(name: string, guardName?: string, description?: string): Promise<PermissionRecord>
|
|
211
|
+
deletePermission(id: number): Promise<void>
|
|
212
|
+
getAllPermissions(guardName?: string): Promise<PermissionRecord[]>
|
|
213
|
+
getUserRoles(userId: number): Promise<RoleRecord[]>
|
|
214
|
+
assignRoleToUser(userId: number, roleId: number): Promise<void>
|
|
215
|
+
removeRoleFromUser(userId: number, roleId: number): Promise<void>
|
|
216
|
+
removeAllRolesFromUser(userId: number): Promise<void>
|
|
217
|
+
syncUserRoles(userId: number, roleIds: number[]): Promise<void>
|
|
218
|
+
getUserDirectPermissions(userId: number): Promise<PermissionRecord[]>
|
|
219
|
+
assignPermissionToUser(userId: number, permissionId: number): Promise<void>
|
|
220
|
+
removePermissionFromUser(userId: number, permissionId: number): Promise<void>
|
|
221
|
+
removeAllPermissionsFromUser(userId: number): Promise<void>
|
|
222
|
+
syncUserPermissions(userId: number, permissionIds: number[]): Promise<void>
|
|
223
|
+
getRolePermissions(roleId: number): Promise<PermissionRecord[]>
|
|
224
|
+
assignPermissionToRole(roleId: number, permissionId: number): Promise<void>
|
|
225
|
+
removePermissionFromRole(roleId: number, permissionId: number): Promise<void>
|
|
226
|
+
syncRolePermissions(roleId: number, permissionIds: number[]): Promise<void>
|
|
227
|
+
}
|
|
228
|
+
// ─── Authorizable Mixin (add to user objects) ───────────────────
|
|
229
|
+
export declare interface RbacMethods {
|
|
230
|
+
hasRole(roleName: string, guardName?: string): Promise<boolean>
|
|
231
|
+
hasAnyRole(roleNames: string[], guardName?: string): Promise<boolean>
|
|
232
|
+
hasAllRoles(roleNames: string[], guardName?: string): Promise<boolean>
|
|
233
|
+
hasPermission(permissionName: string, guardName?: string): Promise<boolean>
|
|
234
|
+
hasAnyPermission(permissionNames: string[], guardName?: string): Promise<boolean>
|
|
235
|
+
hasAllPermissions(permissionNames: string[], guardName?: string): Promise<boolean>
|
|
236
|
+
getRoles(): Promise<RoleRecord[]>
|
|
237
|
+
getPermissions(): Promise<PermissionRecord[]>
|
|
238
|
+
assignRole(roleName: string, guardName?: string): Promise<void>
|
|
239
|
+
removeRole(roleName: string, guardName?: string): Promise<void>
|
|
240
|
+
syncRoles(roleNames: string[], guardName?: string): Promise<void>
|
|
241
|
+
givePermission(permissionName: string, guardName?: string): Promise<void>
|
|
242
|
+
revokePermission(permissionName: string, guardName?: string): Promise<void>
|
|
243
|
+
syncPermissions(permissionNames: string[], guardName?: string): Promise<void>
|
|
244
|
+
}
|
|
245
|
+
// Use the row/instance shape from orm so role helpers operate on the
|
|
246
|
+
// authenticated user object, not the User class constructor.
|
|
247
|
+
declare type UserModel = OrmUserModel;
|
|
248
|
+
/**
|
|
249
|
+
* FIFO-bounded Map. Wraps Map with a hard size cap; on overflow, the
|
|
250
|
+
* oldest entry (Map insertion order) is evicted. Used for the RBAC
|
|
251
|
+
* per-user caches because the previous unbounded `Map<number, ...>`
|
|
252
|
+
* grew without limit across the process lifetime — a long-running
|
|
253
|
+
* server serving many distinct users would OOM eventually
|
|
254
|
+
* (stacksjs/stacks#1860 M-5). Same shape as `BoundedMap` in
|
|
255
|
+
* `@stacksjs/router/stacks-router.ts`.
|
|
256
|
+
*/
|
|
257
|
+
declare class BoundedMap<K, V> {
|
|
258
|
+
constructor(max: number);
|
|
259
|
+
get(key: K): V | undefined;
|
|
260
|
+
has(key: K): boolean;
|
|
261
|
+
set(key: K, value: V): this;
|
|
262
|
+
delete(key: K): boolean;
|
|
263
|
+
clear(): void;
|
|
264
|
+
}
|
|
265
|
+
export default Rbac;
|