@uniforge/platform-core 0.1.0-alpha.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.
- package/dist/auth/index.d.cts +184 -0
- package/dist/auth/index.d.ts +184 -0
- package/dist/auth/index.js +62 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +33 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/billing/index.d.cts +213 -0
- package/dist/billing/index.d.ts +213 -0
- package/dist/billing/index.js +43 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/billing/index.mjs +16 -0
- package/dist/billing/index.mjs.map +1 -0
- package/dist/graphql/index.d.cts +100 -0
- package/dist/graphql/index.d.ts +100 -0
- package/dist/graphql/index.js +19 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/graphql/index.mjs +1 -0
- package/dist/graphql/index.mjs.map +1 -0
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/dist/multi-store/index.d.cts +242 -0
- package/dist/multi-store/index.d.ts +242 -0
- package/dist/multi-store/index.js +53 -0
- package/dist/multi-store/index.js.map +1 -0
- package/dist/multi-store/index.mjs +23 -0
- package/dist/multi-store/index.mjs.map +1 -0
- package/dist/multi-tenant/index.d.cts +64 -0
- package/dist/multi-tenant/index.d.ts +64 -0
- package/dist/multi-tenant/index.js +19 -0
- package/dist/multi-tenant/index.js.map +1 -0
- package/dist/multi-tenant/index.mjs +1 -0
- package/dist/multi-tenant/index.mjs.map +1 -0
- package/dist/performance/index.d.cts +118 -0
- package/dist/performance/index.d.ts +118 -0
- package/dist/performance/index.js +19 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/performance/index.mjs +1 -0
- package/dist/performance/index.mjs.map +1 -0
- package/dist/platform/index.d.cts +156 -0
- package/dist/platform/index.d.ts +156 -0
- package/dist/platform/index.js +64 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/index.mjs +37 -0
- package/dist/platform/index.mjs.map +1 -0
- package/dist/rbac/index.d.cts +140 -0
- package/dist/rbac/index.d.ts +140 -0
- package/dist/rbac/index.js +55 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/index.mjs +27 -0
- package/dist/rbac/index.mjs.map +1 -0
- package/dist/registry-efvajmOd.d.cts +118 -0
- package/dist/registry-efvajmOd.d.ts +118 -0
- package/dist/security/index.d.cts +148 -0
- package/dist/security/index.d.ts +148 -0
- package/dist/security/index.js +40 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/index.mjs +13 -0
- package/dist/security/index.mjs.map +1 -0
- package/dist/types-CgnJiK8Z.d.cts +74 -0
- package/dist/types-CgnJiK8Z.d.ts +74 -0
- package/dist/webhooks/index.d.cts +114 -0
- package/dist/webhooks/index.d.ts +114 -0
- package/dist/webhooks/index.js +19 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/index.mjs +1 -0
- package/dist/webhooks/index.mjs.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic RBAC types.
|
|
3
|
+
*
|
|
4
|
+
* Defines roles, permissions, and shop member types used across
|
|
5
|
+
* all platform adapters for role-based access control.
|
|
6
|
+
*/
|
|
7
|
+
/** Available roles in descending privilege order. */
|
|
8
|
+
type Role = 'owner' | 'admin' | 'staff' | 'collaborator';
|
|
9
|
+
/** Role hierarchy from highest to lowest privilege. */
|
|
10
|
+
declare const ROLE_HIERARCHY: readonly Role[];
|
|
11
|
+
/** A shop member with role and optional custom permissions. */
|
|
12
|
+
interface ShopMember {
|
|
13
|
+
id: string;
|
|
14
|
+
shopDomain: string;
|
|
15
|
+
userId: number;
|
|
16
|
+
email: string;
|
|
17
|
+
role: Role;
|
|
18
|
+
customPermissions: string[] | null;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
}
|
|
22
|
+
/** Input for creating or updating a shop member (upsert). */
|
|
23
|
+
interface UpsertShopMemberInput {
|
|
24
|
+
shopDomain: string;
|
|
25
|
+
userId: number;
|
|
26
|
+
email: string;
|
|
27
|
+
role: Role;
|
|
28
|
+
customPermissions?: string[];
|
|
29
|
+
}
|
|
30
|
+
/** Input for updating an existing shop member. */
|
|
31
|
+
interface UpdateShopMemberInput {
|
|
32
|
+
role?: Role;
|
|
33
|
+
email?: string;
|
|
34
|
+
customPermissions?: string[];
|
|
35
|
+
}
|
|
36
|
+
/** Maps each role to its default set of permissions. */
|
|
37
|
+
type RolePermissionMap = Record<Role, string[]>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Platform-agnostic RBAC service interface.
|
|
41
|
+
*
|
|
42
|
+
* Defines the contract for managing shop members and checking
|
|
43
|
+
* permissions. Core RBAC service provides the Prisma-backed
|
|
44
|
+
* implementation.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/** Core RBAC service for member management and permission checks. */
|
|
48
|
+
interface RBACService {
|
|
49
|
+
/** Create or update a shop member (upsert by shopDomain + userId). */
|
|
50
|
+
upsertMember(input: UpsertShopMemberInput): Promise<ShopMember>;
|
|
51
|
+
/** Get a shop member by shop domain and user ID. */
|
|
52
|
+
getMember(shopDomain: string, userId: number): Promise<ShopMember | null>;
|
|
53
|
+
/** List all members for a shop. */
|
|
54
|
+
listMembers(shopDomain: string): Promise<ShopMember[]>;
|
|
55
|
+
/** Update an existing shop member's role or permissions. */
|
|
56
|
+
updateMember(shopDomain: string, userId: number, input: UpdateShopMemberInput): Promise<ShopMember>;
|
|
57
|
+
/** Remove a shop member. */
|
|
58
|
+
removeMember(shopDomain: string, userId: number): Promise<void>;
|
|
59
|
+
/** Check if a member has a specific permission. */
|
|
60
|
+
hasPermission(shopDomain: string, userId: number, permission: string): Promise<boolean>;
|
|
61
|
+
/** Get the effective permissions for a member (role defaults + custom). */
|
|
62
|
+
getEffectivePermissions(shopDomain: string, userId: number): Promise<string[]>;
|
|
63
|
+
/** Check if a role meets a minimum required role level. */
|
|
64
|
+
isRoleAtLeast(role: Role, minimumRole: Role): boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* RBAC middleware interfaces for route-level permission enforcement.
|
|
69
|
+
*
|
|
70
|
+
* Sits after AuthMiddleware and TenantMiddleware in the chain,
|
|
71
|
+
* enforcing role-based access on protected routes.
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/** Maps a route pattern + HTTP method to a required permission. */
|
|
75
|
+
interface RoutePermission {
|
|
76
|
+
/** Glob pattern for the route path (e.g., '/api/products/**'). */
|
|
77
|
+
pattern: string;
|
|
78
|
+
/** HTTP method to match (e.g., 'GET', 'POST'). Use '*' for all methods. */
|
|
79
|
+
method: string;
|
|
80
|
+
/** The permission string required to access this route. */
|
|
81
|
+
permission: string;
|
|
82
|
+
}
|
|
83
|
+
/** Configuration for the RBAC middleware. */
|
|
84
|
+
interface RBACMiddlewareConfig {
|
|
85
|
+
/** Route permission rules to enforce. */
|
|
86
|
+
routes: RoutePermission[];
|
|
87
|
+
/** Function to look up a shop member by domain and user ID. */
|
|
88
|
+
getMember: (shopDomain: string, userId: number) => Promise<{
|
|
89
|
+
role: Role;
|
|
90
|
+
customPermissions: string[] | null;
|
|
91
|
+
} | null>;
|
|
92
|
+
/** Whether to auto-provision account owners as 'owner' role. Defaults to true. */
|
|
93
|
+
autoProvisionOwner?: boolean;
|
|
94
|
+
/** Callback for auto-provisioning a new owner member. */
|
|
95
|
+
onAutoProvision?: (shopDomain: string, userId: number, email: string) => Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
/** RBAC authorization result when access is granted. */
|
|
98
|
+
interface RBACResultGranted {
|
|
99
|
+
type: 'granted';
|
|
100
|
+
role: Role;
|
|
101
|
+
permission: string;
|
|
102
|
+
}
|
|
103
|
+
/** RBAC authorization result when access is denied. */
|
|
104
|
+
interface RBACResultDenied {
|
|
105
|
+
type: 'denied';
|
|
106
|
+
role: Role | null;
|
|
107
|
+
permission: string;
|
|
108
|
+
reason: string;
|
|
109
|
+
}
|
|
110
|
+
/** RBAC authorization result when check is skipped (e.g., offline session). */
|
|
111
|
+
interface RBACResultSkipped {
|
|
112
|
+
type: 'skipped';
|
|
113
|
+
reason: string;
|
|
114
|
+
}
|
|
115
|
+
/** Discriminated union of RBAC authorization results. */
|
|
116
|
+
type RBACResult = RBACResultGranted | RBACResultDenied | RBACResultSkipped;
|
|
117
|
+
/** User identity extracted from the authenticated session. */
|
|
118
|
+
interface SessionUser {
|
|
119
|
+
userId: number;
|
|
120
|
+
email: string;
|
|
121
|
+
isAccountOwner: boolean;
|
|
122
|
+
}
|
|
123
|
+
/** RBAC middleware for route-level permission checks. */
|
|
124
|
+
interface RBACMiddleware {
|
|
125
|
+
/** Authorize a request against configured route permissions. */
|
|
126
|
+
authorize(input: {
|
|
127
|
+
url: string;
|
|
128
|
+
method: string;
|
|
129
|
+
shopDomain: string;
|
|
130
|
+
user: SessionUser | null;
|
|
131
|
+
}): Promise<RBACResult>;
|
|
132
|
+
}
|
|
133
|
+
/** Error thrown when a permission check fails. */
|
|
134
|
+
declare class PermissionDeniedError extends Error {
|
|
135
|
+
readonly permission: string;
|
|
136
|
+
readonly role: Role | null;
|
|
137
|
+
constructor(permission: string, role: Role | null);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { PermissionDeniedError, type RBACMiddleware, type RBACMiddlewareConfig, type RBACResult, type RBACResultDenied, type RBACResultGranted, type RBACResultSkipped, type RBACService, ROLE_HIERARCHY, type Role, type RolePermissionMap, type RoutePermission, type SessionUser, type ShopMember, type UpdateShopMemberInput, type UpsertShopMemberInput };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic RBAC types.
|
|
3
|
+
*
|
|
4
|
+
* Defines roles, permissions, and shop member types used across
|
|
5
|
+
* all platform adapters for role-based access control.
|
|
6
|
+
*/
|
|
7
|
+
/** Available roles in descending privilege order. */
|
|
8
|
+
type Role = 'owner' | 'admin' | 'staff' | 'collaborator';
|
|
9
|
+
/** Role hierarchy from highest to lowest privilege. */
|
|
10
|
+
declare const ROLE_HIERARCHY: readonly Role[];
|
|
11
|
+
/** A shop member with role and optional custom permissions. */
|
|
12
|
+
interface ShopMember {
|
|
13
|
+
id: string;
|
|
14
|
+
shopDomain: string;
|
|
15
|
+
userId: number;
|
|
16
|
+
email: string;
|
|
17
|
+
role: Role;
|
|
18
|
+
customPermissions: string[] | null;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
}
|
|
22
|
+
/** Input for creating or updating a shop member (upsert). */
|
|
23
|
+
interface UpsertShopMemberInput {
|
|
24
|
+
shopDomain: string;
|
|
25
|
+
userId: number;
|
|
26
|
+
email: string;
|
|
27
|
+
role: Role;
|
|
28
|
+
customPermissions?: string[];
|
|
29
|
+
}
|
|
30
|
+
/** Input for updating an existing shop member. */
|
|
31
|
+
interface UpdateShopMemberInput {
|
|
32
|
+
role?: Role;
|
|
33
|
+
email?: string;
|
|
34
|
+
customPermissions?: string[];
|
|
35
|
+
}
|
|
36
|
+
/** Maps each role to its default set of permissions. */
|
|
37
|
+
type RolePermissionMap = Record<Role, string[]>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Platform-agnostic RBAC service interface.
|
|
41
|
+
*
|
|
42
|
+
* Defines the contract for managing shop members and checking
|
|
43
|
+
* permissions. Core RBAC service provides the Prisma-backed
|
|
44
|
+
* implementation.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/** Core RBAC service for member management and permission checks. */
|
|
48
|
+
interface RBACService {
|
|
49
|
+
/** Create or update a shop member (upsert by shopDomain + userId). */
|
|
50
|
+
upsertMember(input: UpsertShopMemberInput): Promise<ShopMember>;
|
|
51
|
+
/** Get a shop member by shop domain and user ID. */
|
|
52
|
+
getMember(shopDomain: string, userId: number): Promise<ShopMember | null>;
|
|
53
|
+
/** List all members for a shop. */
|
|
54
|
+
listMembers(shopDomain: string): Promise<ShopMember[]>;
|
|
55
|
+
/** Update an existing shop member's role or permissions. */
|
|
56
|
+
updateMember(shopDomain: string, userId: number, input: UpdateShopMemberInput): Promise<ShopMember>;
|
|
57
|
+
/** Remove a shop member. */
|
|
58
|
+
removeMember(shopDomain: string, userId: number): Promise<void>;
|
|
59
|
+
/** Check if a member has a specific permission. */
|
|
60
|
+
hasPermission(shopDomain: string, userId: number, permission: string): Promise<boolean>;
|
|
61
|
+
/** Get the effective permissions for a member (role defaults + custom). */
|
|
62
|
+
getEffectivePermissions(shopDomain: string, userId: number): Promise<string[]>;
|
|
63
|
+
/** Check if a role meets a minimum required role level. */
|
|
64
|
+
isRoleAtLeast(role: Role, minimumRole: Role): boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* RBAC middleware interfaces for route-level permission enforcement.
|
|
69
|
+
*
|
|
70
|
+
* Sits after AuthMiddleware and TenantMiddleware in the chain,
|
|
71
|
+
* enforcing role-based access on protected routes.
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/** Maps a route pattern + HTTP method to a required permission. */
|
|
75
|
+
interface RoutePermission {
|
|
76
|
+
/** Glob pattern for the route path (e.g., '/api/products/**'). */
|
|
77
|
+
pattern: string;
|
|
78
|
+
/** HTTP method to match (e.g., 'GET', 'POST'). Use '*' for all methods. */
|
|
79
|
+
method: string;
|
|
80
|
+
/** The permission string required to access this route. */
|
|
81
|
+
permission: string;
|
|
82
|
+
}
|
|
83
|
+
/** Configuration for the RBAC middleware. */
|
|
84
|
+
interface RBACMiddlewareConfig {
|
|
85
|
+
/** Route permission rules to enforce. */
|
|
86
|
+
routes: RoutePermission[];
|
|
87
|
+
/** Function to look up a shop member by domain and user ID. */
|
|
88
|
+
getMember: (shopDomain: string, userId: number) => Promise<{
|
|
89
|
+
role: Role;
|
|
90
|
+
customPermissions: string[] | null;
|
|
91
|
+
} | null>;
|
|
92
|
+
/** Whether to auto-provision account owners as 'owner' role. Defaults to true. */
|
|
93
|
+
autoProvisionOwner?: boolean;
|
|
94
|
+
/** Callback for auto-provisioning a new owner member. */
|
|
95
|
+
onAutoProvision?: (shopDomain: string, userId: number, email: string) => Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
/** RBAC authorization result when access is granted. */
|
|
98
|
+
interface RBACResultGranted {
|
|
99
|
+
type: 'granted';
|
|
100
|
+
role: Role;
|
|
101
|
+
permission: string;
|
|
102
|
+
}
|
|
103
|
+
/** RBAC authorization result when access is denied. */
|
|
104
|
+
interface RBACResultDenied {
|
|
105
|
+
type: 'denied';
|
|
106
|
+
role: Role | null;
|
|
107
|
+
permission: string;
|
|
108
|
+
reason: string;
|
|
109
|
+
}
|
|
110
|
+
/** RBAC authorization result when check is skipped (e.g., offline session). */
|
|
111
|
+
interface RBACResultSkipped {
|
|
112
|
+
type: 'skipped';
|
|
113
|
+
reason: string;
|
|
114
|
+
}
|
|
115
|
+
/** Discriminated union of RBAC authorization results. */
|
|
116
|
+
type RBACResult = RBACResultGranted | RBACResultDenied | RBACResultSkipped;
|
|
117
|
+
/** User identity extracted from the authenticated session. */
|
|
118
|
+
interface SessionUser {
|
|
119
|
+
userId: number;
|
|
120
|
+
email: string;
|
|
121
|
+
isAccountOwner: boolean;
|
|
122
|
+
}
|
|
123
|
+
/** RBAC middleware for route-level permission checks. */
|
|
124
|
+
interface RBACMiddleware {
|
|
125
|
+
/** Authorize a request against configured route permissions. */
|
|
126
|
+
authorize(input: {
|
|
127
|
+
url: string;
|
|
128
|
+
method: string;
|
|
129
|
+
shopDomain: string;
|
|
130
|
+
user: SessionUser | null;
|
|
131
|
+
}): Promise<RBACResult>;
|
|
132
|
+
}
|
|
133
|
+
/** Error thrown when a permission check fails. */
|
|
134
|
+
declare class PermissionDeniedError extends Error {
|
|
135
|
+
readonly permission: string;
|
|
136
|
+
readonly role: Role | null;
|
|
137
|
+
constructor(permission: string, role: Role | null);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { PermissionDeniedError, type RBACMiddleware, type RBACMiddlewareConfig, type RBACResult, type RBACResultDenied, type RBACResultGranted, type RBACResultSkipped, type RBACService, ROLE_HIERARCHY, type Role, type RolePermissionMap, type RoutePermission, type SessionUser, type ShopMember, type UpdateShopMemberInput, type UpsertShopMemberInput };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/rbac/index.ts
|
|
21
|
+
var rbac_exports = {};
|
|
22
|
+
__export(rbac_exports, {
|
|
23
|
+
PermissionDeniedError: () => PermissionDeniedError,
|
|
24
|
+
ROLE_HIERARCHY: () => ROLE_HIERARCHY
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(rbac_exports);
|
|
27
|
+
|
|
28
|
+
// src/rbac/types.ts
|
|
29
|
+
var ROLE_HIERARCHY = [
|
|
30
|
+
"owner",
|
|
31
|
+
"admin",
|
|
32
|
+
"staff",
|
|
33
|
+
"collaborator"
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// src/rbac/middleware.ts
|
|
37
|
+
var PermissionDeniedError = class extends Error {
|
|
38
|
+
permission;
|
|
39
|
+
role;
|
|
40
|
+
constructor(permission, role) {
|
|
41
|
+
const roleInfo = role ? `role "${role}"` : "unknown role";
|
|
42
|
+
super(
|
|
43
|
+
`Permission "${permission}" denied for ${roleInfo}`
|
|
44
|
+
);
|
|
45
|
+
this.name = "PermissionDeniedError";
|
|
46
|
+
this.permission = permission;
|
|
47
|
+
this.role = role;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
51
|
+
0 && (module.exports = {
|
|
52
|
+
PermissionDeniedError,
|
|
53
|
+
ROLE_HIERARCHY
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/rbac/index.ts","../../src/rbac/types.ts","../../src/rbac/middleware.ts"],"sourcesContent":["/**\n * @uniforge/platform-core/rbac\n *\n * Platform-agnostic RBAC interfaces for role-based access control,\n * shop member management, and route-level permission enforcement.\n */\n\nexport type {\n Role,\n ShopMember,\n UpsertShopMemberInput,\n UpdateShopMemberInput,\n RolePermissionMap,\n} from './types.js';\n\nexport { ROLE_HIERARCHY } from './types.js';\n\nexport type { RBACService } from './service.js';\n\nexport type {\n RoutePermission,\n RBACMiddlewareConfig,\n RBACResultGranted,\n RBACResultDenied,\n RBACResultSkipped,\n RBACResult,\n SessionUser,\n RBACMiddleware,\n} from './middleware.js';\n\nexport { PermissionDeniedError } from './middleware.js';\n","/**\n * Platform-agnostic RBAC types.\n *\n * Defines roles, permissions, and shop member types used across\n * all platform adapters for role-based access control.\n */\n\n/** Available roles in descending privilege order. */\nexport type Role = 'owner' | 'admin' | 'staff' | 'collaborator';\n\n/** Role hierarchy from highest to lowest privilege. */\nexport const ROLE_HIERARCHY: readonly Role[] = [\n 'owner',\n 'admin',\n 'staff',\n 'collaborator',\n] as const;\n\n/** A shop member with role and optional custom permissions. */\nexport interface ShopMember {\n id: string;\n shopDomain: string;\n userId: number;\n email: string;\n role: Role;\n customPermissions: string[] | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** Input for creating or updating a shop member (upsert). */\nexport interface UpsertShopMemberInput {\n shopDomain: string;\n userId: number;\n email: string;\n role: Role;\n customPermissions?: string[];\n}\n\n/** Input for updating an existing shop member. */\nexport interface UpdateShopMemberInput {\n role?: Role;\n email?: string;\n customPermissions?: string[];\n}\n\n/** Maps each role to its default set of permissions. */\nexport type RolePermissionMap = Record<Role, string[]>;\n","/**\n * RBAC middleware interfaces for route-level permission enforcement.\n *\n * Sits after AuthMiddleware and TenantMiddleware in the chain,\n * enforcing role-based access on protected routes.\n */\n\nimport type { Role } from './types.js';\n\n/** Maps a route pattern + HTTP method to a required permission. */\nexport interface RoutePermission {\n /** Glob pattern for the route path (e.g., '/api/products/**'). */\n pattern: string;\n /** HTTP method to match (e.g., 'GET', 'POST'). Use '*' for all methods. */\n method: string;\n /** The permission string required to access this route. */\n permission: string;\n}\n\n/** Configuration for the RBAC middleware. */\nexport interface RBACMiddlewareConfig {\n /** Route permission rules to enforce. */\n routes: RoutePermission[];\n /** Function to look up a shop member by domain and user ID. */\n getMember: (shopDomain: string, userId: number) => Promise<{\n role: Role;\n customPermissions: string[] | null;\n } | null>;\n /** Whether to auto-provision account owners as 'owner' role. Defaults to true. */\n autoProvisionOwner?: boolean;\n /** Callback for auto-provisioning a new owner member. */\n onAutoProvision?: (shopDomain: string, userId: number, email: string) => Promise<void>;\n}\n\n/** RBAC authorization result when access is granted. */\nexport interface RBACResultGranted {\n type: 'granted';\n role: Role;\n permission: string;\n}\n\n/** RBAC authorization result when access is denied. */\nexport interface RBACResultDenied {\n type: 'denied';\n role: Role | null;\n permission: string;\n reason: string;\n}\n\n/** RBAC authorization result when check is skipped (e.g., offline session). */\nexport interface RBACResultSkipped {\n type: 'skipped';\n reason: string;\n}\n\n/** Discriminated union of RBAC authorization results. */\nexport type RBACResult = RBACResultGranted | RBACResultDenied | RBACResultSkipped;\n\n/** User identity extracted from the authenticated session. */\nexport interface SessionUser {\n userId: number;\n email: string;\n isAccountOwner: boolean;\n}\n\n/** RBAC middleware for route-level permission checks. */\nexport interface RBACMiddleware {\n /** Authorize a request against configured route permissions. */\n authorize(input: {\n url: string;\n method: string;\n shopDomain: string;\n user: SessionUser | null;\n }): Promise<RBACResult>;\n}\n\n/** Error thrown when a permission check fails. */\nexport class PermissionDeniedError extends Error {\n public readonly permission: string;\n public readonly role: Role | null;\n\n constructor(permission: string, role: Role | null) {\n const roleInfo = role ? `role \"${role}\"` : 'unknown role';\n super(\n `Permission \"${permission}\" denied for ${roleInfo}`,\n );\n this.name = 'PermissionDeniedError';\n this.permission = permission;\n this.role = role;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACWO,IAAM,iBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC6DO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EAEhB,YAAY,YAAoB,MAAmB;AACjD,UAAM,WAAW,OAAO,SAAS,IAAI,MAAM;AAC3C;AAAA,MACE,eAAe,UAAU,gBAAgB,QAAQ;AAAA,IACnD;AACA,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,OAAO;AAAA,EACd;AACF;","names":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/rbac/types.ts
|
|
2
|
+
var ROLE_HIERARCHY = [
|
|
3
|
+
"owner",
|
|
4
|
+
"admin",
|
|
5
|
+
"staff",
|
|
6
|
+
"collaborator"
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
// src/rbac/middleware.ts
|
|
10
|
+
var PermissionDeniedError = class extends Error {
|
|
11
|
+
permission;
|
|
12
|
+
role;
|
|
13
|
+
constructor(permission, role) {
|
|
14
|
+
const roleInfo = role ? `role "${role}"` : "unknown role";
|
|
15
|
+
super(
|
|
16
|
+
`Permission "${permission}" denied for ${roleInfo}`
|
|
17
|
+
);
|
|
18
|
+
this.name = "PermissionDeniedError";
|
|
19
|
+
this.permission = permission;
|
|
20
|
+
this.role = role;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
PermissionDeniedError,
|
|
25
|
+
ROLE_HIERARCHY
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/rbac/types.ts","../../src/rbac/middleware.ts"],"sourcesContent":["/**\n * Platform-agnostic RBAC types.\n *\n * Defines roles, permissions, and shop member types used across\n * all platform adapters for role-based access control.\n */\n\n/** Available roles in descending privilege order. */\nexport type Role = 'owner' | 'admin' | 'staff' | 'collaborator';\n\n/** Role hierarchy from highest to lowest privilege. */\nexport const ROLE_HIERARCHY: readonly Role[] = [\n 'owner',\n 'admin',\n 'staff',\n 'collaborator',\n] as const;\n\n/** A shop member with role and optional custom permissions. */\nexport interface ShopMember {\n id: string;\n shopDomain: string;\n userId: number;\n email: string;\n role: Role;\n customPermissions: string[] | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** Input for creating or updating a shop member (upsert). */\nexport interface UpsertShopMemberInput {\n shopDomain: string;\n userId: number;\n email: string;\n role: Role;\n customPermissions?: string[];\n}\n\n/** Input for updating an existing shop member. */\nexport interface UpdateShopMemberInput {\n role?: Role;\n email?: string;\n customPermissions?: string[];\n}\n\n/** Maps each role to its default set of permissions. */\nexport type RolePermissionMap = Record<Role, string[]>;\n","/**\n * RBAC middleware interfaces for route-level permission enforcement.\n *\n * Sits after AuthMiddleware and TenantMiddleware in the chain,\n * enforcing role-based access on protected routes.\n */\n\nimport type { Role } from './types.js';\n\n/** Maps a route pattern + HTTP method to a required permission. */\nexport interface RoutePermission {\n /** Glob pattern for the route path (e.g., '/api/products/**'). */\n pattern: string;\n /** HTTP method to match (e.g., 'GET', 'POST'). Use '*' for all methods. */\n method: string;\n /** The permission string required to access this route. */\n permission: string;\n}\n\n/** Configuration for the RBAC middleware. */\nexport interface RBACMiddlewareConfig {\n /** Route permission rules to enforce. */\n routes: RoutePermission[];\n /** Function to look up a shop member by domain and user ID. */\n getMember: (shopDomain: string, userId: number) => Promise<{\n role: Role;\n customPermissions: string[] | null;\n } | null>;\n /** Whether to auto-provision account owners as 'owner' role. Defaults to true. */\n autoProvisionOwner?: boolean;\n /** Callback for auto-provisioning a new owner member. */\n onAutoProvision?: (shopDomain: string, userId: number, email: string) => Promise<void>;\n}\n\n/** RBAC authorization result when access is granted. */\nexport interface RBACResultGranted {\n type: 'granted';\n role: Role;\n permission: string;\n}\n\n/** RBAC authorization result when access is denied. */\nexport interface RBACResultDenied {\n type: 'denied';\n role: Role | null;\n permission: string;\n reason: string;\n}\n\n/** RBAC authorization result when check is skipped (e.g., offline session). */\nexport interface RBACResultSkipped {\n type: 'skipped';\n reason: string;\n}\n\n/** Discriminated union of RBAC authorization results. */\nexport type RBACResult = RBACResultGranted | RBACResultDenied | RBACResultSkipped;\n\n/** User identity extracted from the authenticated session. */\nexport interface SessionUser {\n userId: number;\n email: string;\n isAccountOwner: boolean;\n}\n\n/** RBAC middleware for route-level permission checks. */\nexport interface RBACMiddleware {\n /** Authorize a request against configured route permissions. */\n authorize(input: {\n url: string;\n method: string;\n shopDomain: string;\n user: SessionUser | null;\n }): Promise<RBACResult>;\n}\n\n/** Error thrown when a permission check fails. */\nexport class PermissionDeniedError extends Error {\n public readonly permission: string;\n public readonly role: Role | null;\n\n constructor(permission: string, role: Role | null) {\n const roleInfo = role ? `role \"${role}\"` : 'unknown role';\n super(\n `Permission \"${permission}\" denied for ${roleInfo}`,\n );\n this.name = 'PermissionDeniedError';\n this.permission = permission;\n this.role = role;\n }\n}\n"],"mappings":";AAWO,IAAM,iBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC6DO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EAEhB,YAAY,YAAoB,MAAmB;AACjD,UAAM,WAAW,OAAO,SAAS,IAAI,MAAM;AAC3C;AAAA,MACE,eAAe,UAAU,gBAAgB,QAAQ;AAAA,IACnD;AACA,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,OAAO;AAAA,EACd;AACF;","names":[]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform abstraction core types.
|
|
3
|
+
*/
|
|
4
|
+
/** Unique identifier for a platform (e.g., 'shopify', 'woocommerce') */
|
|
5
|
+
type PlatformId = string;
|
|
6
|
+
/** Basic platform information */
|
|
7
|
+
interface PlatformInfo {
|
|
8
|
+
readonly id: PlatformId;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly version: string;
|
|
11
|
+
readonly description: string;
|
|
12
|
+
}
|
|
13
|
+
/** Platform-specific configuration passed to the provider */
|
|
14
|
+
interface PlatformConfig {
|
|
15
|
+
platformId: PlatformId;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** Result of platform configuration validation */
|
|
19
|
+
interface PlatformValidationResult {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
errors: PlatformValidationError[];
|
|
22
|
+
}
|
|
23
|
+
interface PlatformValidationError {
|
|
24
|
+
field: string;
|
|
25
|
+
message: string;
|
|
26
|
+
code: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Platform capability detection types.
|
|
31
|
+
*
|
|
32
|
+
* Declares what features each platform adapter supports,
|
|
33
|
+
* enabling graceful feature degradation.
|
|
34
|
+
*/
|
|
35
|
+
interface AuthCapabilities {
|
|
36
|
+
tokenExchange: boolean;
|
|
37
|
+
oauth: boolean;
|
|
38
|
+
apiKeys: boolean;
|
|
39
|
+
sessionManagement: boolean;
|
|
40
|
+
}
|
|
41
|
+
interface BillingCapabilities {
|
|
42
|
+
subscriptions: boolean;
|
|
43
|
+
oneTimeCharges: boolean;
|
|
44
|
+
usageBased: boolean;
|
|
45
|
+
trialSupport: boolean;
|
|
46
|
+
}
|
|
47
|
+
interface WebhookCapabilities {
|
|
48
|
+
supported: boolean;
|
|
49
|
+
verificationMethod: 'hmac' | 'signature' | 'none';
|
|
50
|
+
supportsRegistration: boolean;
|
|
51
|
+
}
|
|
52
|
+
interface GraphQLCapabilities {
|
|
53
|
+
supported: boolean;
|
|
54
|
+
rateLimiting: boolean;
|
|
55
|
+
caching: boolean;
|
|
56
|
+
}
|
|
57
|
+
interface CommerceCapabilities {
|
|
58
|
+
products: boolean;
|
|
59
|
+
orders: boolean;
|
|
60
|
+
customers: boolean;
|
|
61
|
+
inventory: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Full capability declaration for a platform adapter */
|
|
64
|
+
interface PlatformCapabilities {
|
|
65
|
+
auth: AuthCapabilities;
|
|
66
|
+
billing: BillingCapabilities;
|
|
67
|
+
webhooks: WebhookCapabilities;
|
|
68
|
+
graphql: GraphQLCapabilities;
|
|
69
|
+
rbac: boolean;
|
|
70
|
+
multiStore: boolean;
|
|
71
|
+
commerce: CommerceCapabilities;
|
|
72
|
+
}
|
|
73
|
+
/** Default capabilities for platforms that don't declare specific support */
|
|
74
|
+
declare const DEFAULT_CAPABILITIES: PlatformCapabilities;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* PlatformProvider interface — the main entry point for platform adapters.
|
|
78
|
+
*
|
|
79
|
+
* Extends the existing PlatformAdapter with capability detection
|
|
80
|
+
* and config validation. Each platform adapter (Shopify, WooCommerce, etc.)
|
|
81
|
+
* implements this interface.
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
interface PlatformProvider extends PlatformInfo {
|
|
85
|
+
/** Get the full capabilities of this platform adapter */
|
|
86
|
+
getCapabilities(): PlatformCapabilities;
|
|
87
|
+
/** Validate platform-specific configuration */
|
|
88
|
+
validateConfig(config: PlatformConfig): PlatformValidationResult;
|
|
89
|
+
/** Check if the platform supports a specific capability category */
|
|
90
|
+
supportsAuth(): boolean;
|
|
91
|
+
supportsBilling(): boolean;
|
|
92
|
+
supportsWebhooks(): boolean;
|
|
93
|
+
supportsGraphQL(): boolean;
|
|
94
|
+
supportsRBAC(): boolean;
|
|
95
|
+
supportsMultiStore(): boolean;
|
|
96
|
+
supportsCommerce(): boolean;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* PlatformRegistry interface — manages registered platform adapters.
|
|
101
|
+
*
|
|
102
|
+
* Allows registering, retrieving, and listing available platform providers.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
interface PlatformRegistry {
|
|
106
|
+
/** Register a platform provider */
|
|
107
|
+
register(provider: PlatformProvider): void;
|
|
108
|
+
/** Get a platform provider by ID */
|
|
109
|
+
get(platformId: PlatformId): PlatformProvider | undefined;
|
|
110
|
+
/** Check if a platform is registered */
|
|
111
|
+
has(platformId: PlatformId): boolean;
|
|
112
|
+
/** List all registered platform IDs */
|
|
113
|
+
list(): PlatformId[];
|
|
114
|
+
/** Get all registered providers */
|
|
115
|
+
getAll(): PlatformProvider[];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { type AuthCapabilities as A, type BillingCapabilities as B, type CommerceCapabilities as C, DEFAULT_CAPABILITIES as D, type GraphQLCapabilities as G, type PlatformProvider as P, type WebhookCapabilities as W, type PlatformRegistry as a, type PlatformCapabilities as b, type PlatformId as c, type PlatformInfo as d, type PlatformConfig as e, type PlatformValidationResult as f, type PlatformValidationError as g };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform abstraction core types.
|
|
3
|
+
*/
|
|
4
|
+
/** Unique identifier for a platform (e.g., 'shopify', 'woocommerce') */
|
|
5
|
+
type PlatformId = string;
|
|
6
|
+
/** Basic platform information */
|
|
7
|
+
interface PlatformInfo {
|
|
8
|
+
readonly id: PlatformId;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly version: string;
|
|
11
|
+
readonly description: string;
|
|
12
|
+
}
|
|
13
|
+
/** Platform-specific configuration passed to the provider */
|
|
14
|
+
interface PlatformConfig {
|
|
15
|
+
platformId: PlatformId;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** Result of platform configuration validation */
|
|
19
|
+
interface PlatformValidationResult {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
errors: PlatformValidationError[];
|
|
22
|
+
}
|
|
23
|
+
interface PlatformValidationError {
|
|
24
|
+
field: string;
|
|
25
|
+
message: string;
|
|
26
|
+
code: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Platform capability detection types.
|
|
31
|
+
*
|
|
32
|
+
* Declares what features each platform adapter supports,
|
|
33
|
+
* enabling graceful feature degradation.
|
|
34
|
+
*/
|
|
35
|
+
interface AuthCapabilities {
|
|
36
|
+
tokenExchange: boolean;
|
|
37
|
+
oauth: boolean;
|
|
38
|
+
apiKeys: boolean;
|
|
39
|
+
sessionManagement: boolean;
|
|
40
|
+
}
|
|
41
|
+
interface BillingCapabilities {
|
|
42
|
+
subscriptions: boolean;
|
|
43
|
+
oneTimeCharges: boolean;
|
|
44
|
+
usageBased: boolean;
|
|
45
|
+
trialSupport: boolean;
|
|
46
|
+
}
|
|
47
|
+
interface WebhookCapabilities {
|
|
48
|
+
supported: boolean;
|
|
49
|
+
verificationMethod: 'hmac' | 'signature' | 'none';
|
|
50
|
+
supportsRegistration: boolean;
|
|
51
|
+
}
|
|
52
|
+
interface GraphQLCapabilities {
|
|
53
|
+
supported: boolean;
|
|
54
|
+
rateLimiting: boolean;
|
|
55
|
+
caching: boolean;
|
|
56
|
+
}
|
|
57
|
+
interface CommerceCapabilities {
|
|
58
|
+
products: boolean;
|
|
59
|
+
orders: boolean;
|
|
60
|
+
customers: boolean;
|
|
61
|
+
inventory: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Full capability declaration for a platform adapter */
|
|
64
|
+
interface PlatformCapabilities {
|
|
65
|
+
auth: AuthCapabilities;
|
|
66
|
+
billing: BillingCapabilities;
|
|
67
|
+
webhooks: WebhookCapabilities;
|
|
68
|
+
graphql: GraphQLCapabilities;
|
|
69
|
+
rbac: boolean;
|
|
70
|
+
multiStore: boolean;
|
|
71
|
+
commerce: CommerceCapabilities;
|
|
72
|
+
}
|
|
73
|
+
/** Default capabilities for platforms that don't declare specific support */
|
|
74
|
+
declare const DEFAULT_CAPABILITIES: PlatformCapabilities;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* PlatformProvider interface — the main entry point for platform adapters.
|
|
78
|
+
*
|
|
79
|
+
* Extends the existing PlatformAdapter with capability detection
|
|
80
|
+
* and config validation. Each platform adapter (Shopify, WooCommerce, etc.)
|
|
81
|
+
* implements this interface.
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
interface PlatformProvider extends PlatformInfo {
|
|
85
|
+
/** Get the full capabilities of this platform adapter */
|
|
86
|
+
getCapabilities(): PlatformCapabilities;
|
|
87
|
+
/** Validate platform-specific configuration */
|
|
88
|
+
validateConfig(config: PlatformConfig): PlatformValidationResult;
|
|
89
|
+
/** Check if the platform supports a specific capability category */
|
|
90
|
+
supportsAuth(): boolean;
|
|
91
|
+
supportsBilling(): boolean;
|
|
92
|
+
supportsWebhooks(): boolean;
|
|
93
|
+
supportsGraphQL(): boolean;
|
|
94
|
+
supportsRBAC(): boolean;
|
|
95
|
+
supportsMultiStore(): boolean;
|
|
96
|
+
supportsCommerce(): boolean;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* PlatformRegistry interface — manages registered platform adapters.
|
|
101
|
+
*
|
|
102
|
+
* Allows registering, retrieving, and listing available platform providers.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
interface PlatformRegistry {
|
|
106
|
+
/** Register a platform provider */
|
|
107
|
+
register(provider: PlatformProvider): void;
|
|
108
|
+
/** Get a platform provider by ID */
|
|
109
|
+
get(platformId: PlatformId): PlatformProvider | undefined;
|
|
110
|
+
/** Check if a platform is registered */
|
|
111
|
+
has(platformId: PlatformId): boolean;
|
|
112
|
+
/** List all registered platform IDs */
|
|
113
|
+
list(): PlatformId[];
|
|
114
|
+
/** Get all registered providers */
|
|
115
|
+
getAll(): PlatformProvider[];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { type AuthCapabilities as A, type BillingCapabilities as B, type CommerceCapabilities as C, DEFAULT_CAPABILITIES as D, type GraphQLCapabilities as G, type PlatformProvider as P, type WebhookCapabilities as W, type PlatformRegistry as a, type PlatformCapabilities as b, type PlatformId as c, type PlatformInfo as d, type PlatformConfig as e, type PlatformValidationResult as f, type PlatformValidationError as g };
|