@bsb/registry 1.0.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/README.md +133 -0
- package/bsb-plugin.json +47 -0
- package/lib/.bsb/clients/service-bsb-registry.d.ts +1118 -0
- package/lib/.bsb/clients/service-bsb-registry.d.ts.map +1 -0
- package/lib/.bsb/clients/service-bsb-registry.js +393 -0
- package/lib/.bsb/clients/service-bsb-registry.js.map +1 -0
- package/lib/plugins/service-bsb-registry/auth.d.ts +87 -0
- package/lib/plugins/service-bsb-registry/auth.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry/auth.js +197 -0
- package/lib/plugins/service-bsb-registry/auth.js.map +1 -0
- package/lib/plugins/service-bsb-registry/db/file.d.ts +73 -0
- package/lib/plugins/service-bsb-registry/db/file.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry/db/file.js +588 -0
- package/lib/plugins/service-bsb-registry/db/file.js.map +1 -0
- package/lib/plugins/service-bsb-registry/db/index.d.ts +75 -0
- package/lib/plugins/service-bsb-registry/db/index.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry/db/index.js +24 -0
- package/lib/plugins/service-bsb-registry/db/index.js.map +1 -0
- package/lib/plugins/service-bsb-registry/index.d.ts +1228 -0
- package/lib/plugins/service-bsb-registry/index.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry/index.js +661 -0
- package/lib/plugins/service-bsb-registry/index.js.map +1 -0
- package/lib/plugins/service-bsb-registry/types.d.ts +559 -0
- package/lib/plugins/service-bsb-registry/types.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry/types.js +235 -0
- package/lib/plugins/service-bsb-registry/types.js.map +1 -0
- package/lib/plugins/service-bsb-registry-ui/http-server.d.ts +138 -0
- package/lib/plugins/service-bsb-registry-ui/http-server.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry-ui/http-server.js +1660 -0
- package/lib/plugins/service-bsb-registry-ui/http-server.js.map +1 -0
- package/lib/plugins/service-bsb-registry-ui/index.d.ts +62 -0
- package/lib/plugins/service-bsb-registry-ui/index.d.ts.map +1 -0
- package/lib/plugins/service-bsb-registry-ui/index.js +101 -0
- package/lib/plugins/service-bsb-registry-ui/index.js.map +1 -0
- package/lib/plugins/service-bsb-registry-ui/static/assets/images/apple-touch-icon.png +0 -0
- package/lib/plugins/service-bsb-registry-ui/static/assets/images/favicon-16x16.png +0 -0
- package/lib/plugins/service-bsb-registry-ui/static/assets/images/favicon-32x32.png +0 -0
- package/lib/plugins/service-bsb-registry-ui/static/assets/images/favicon.ico +0 -0
- package/lib/plugins/service-bsb-registry-ui/static/css/style.css +1849 -0
- package/lib/plugins/service-bsb-registry-ui/static/js/app.js +336 -0
- package/lib/plugins/service-bsb-registry-ui/templates/layouts/main.hbs +39 -0
- package/lib/plugins/service-bsb-registry-ui/templates/pages/error.hbs +13 -0
- package/lib/plugins/service-bsb-registry-ui/templates/pages/home.hbs +62 -0
- package/lib/plugins/service-bsb-registry-ui/templates/pages/not-found.hbs +13 -0
- package/lib/plugins/service-bsb-registry-ui/templates/pages/plugin-detail.hbs +537 -0
- package/lib/plugins/service-bsb-registry-ui/templates/pages/plugins.hbs +40 -0
- package/lib/plugins/service-bsb-registry-ui/templates/partials/pagination.hbs +41 -0
- package/lib/plugins/service-bsb-registry-ui/templates/partials/plugin-card.hbs +40 -0
- package/lib/plugins/service-bsb-registry-ui/templates/partials/search-form.hbs +31 -0
- package/lib/schemas/service-bsb-registry-ui.json +57 -0
- package/lib/schemas/service-bsb-registry-ui.plugin.json +73 -0
- package/lib/schemas/service-bsb-registry.json +1883 -0
- package/lib/schemas/service-bsb-registry.plugin.json +68 -0
- package/package.json +60 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthManager = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
/**
|
|
6
|
+
* Authentication and user management for the registry.
|
|
7
|
+
*
|
|
8
|
+
* All persistence is delegated to the RegistryDB instance.
|
|
9
|
+
* AuthManager owns the business logic (permission checks, token
|
|
10
|
+
* construction, permission clamping) but never touches the filesystem.
|
|
11
|
+
*/
|
|
12
|
+
class AuthManager {
|
|
13
|
+
db;
|
|
14
|
+
requireAuth;
|
|
15
|
+
constructor(config, db) {
|
|
16
|
+
this.requireAuth = config.requireAuth;
|
|
17
|
+
this.db = db;
|
|
18
|
+
}
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Lifecycle
|
|
21
|
+
// ============================================================================
|
|
22
|
+
async init(obs) {
|
|
23
|
+
const span = obs.startSpan('AuthManager.init');
|
|
24
|
+
try {
|
|
25
|
+
if (!this.requireAuth) {
|
|
26
|
+
obs.log.info('Authentication disabled');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
obs.log.info('AuthManager initialized (storage delegated to RegistryDB)');
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
span.end();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// User CRUD
|
|
37
|
+
// ============================================================================
|
|
38
|
+
async createUser(obs, name, email, permissions) {
|
|
39
|
+
const now = new Date().toISOString();
|
|
40
|
+
const user = {
|
|
41
|
+
id: (0, crypto_1.randomUUID)(),
|
|
42
|
+
name,
|
|
43
|
+
email,
|
|
44
|
+
active: true,
|
|
45
|
+
permissions,
|
|
46
|
+
createdAt: now,
|
|
47
|
+
updatedAt: now,
|
|
48
|
+
};
|
|
49
|
+
await this.db.createUser(obs, user);
|
|
50
|
+
return user;
|
|
51
|
+
}
|
|
52
|
+
async getUser(obs, userId) {
|
|
53
|
+
return this.db.getUser(obs, userId);
|
|
54
|
+
}
|
|
55
|
+
async getUserByEmail(obs, email) {
|
|
56
|
+
return this.db.getUserByEmail(obs, email);
|
|
57
|
+
}
|
|
58
|
+
async listUsers(obs) {
|
|
59
|
+
return this.db.listUsers(obs);
|
|
60
|
+
}
|
|
61
|
+
async updateUser(obs, userId, updates) {
|
|
62
|
+
return this.db.updateUser(obs, userId, updates);
|
|
63
|
+
}
|
|
64
|
+
async deactivateUser(obs, userId) {
|
|
65
|
+
const result = await this.db.updateUser(obs, userId, { active: false });
|
|
66
|
+
return result !== null;
|
|
67
|
+
}
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// Token management (tied to user)
|
|
70
|
+
// ============================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Create a new API token for a user.
|
|
73
|
+
*
|
|
74
|
+
* `tokenPermissions` if provided must be a subset of the user's permissions.
|
|
75
|
+
* Any permission in `tokenPermissions` that the user does not have is silently
|
|
76
|
+
* dropped. If omitted, the token inherits all user permissions at resolve time.
|
|
77
|
+
*/
|
|
78
|
+
async createToken(obs, userId, label, tokenPermissions, expiresAt) {
|
|
79
|
+
const user = await this.db.getUser(obs, userId);
|
|
80
|
+
if (!user || !user.active)
|
|
81
|
+
return null;
|
|
82
|
+
// Clamp token permissions to user permissions (token can never exceed user)
|
|
83
|
+
let perms;
|
|
84
|
+
if (tokenPermissions) {
|
|
85
|
+
perms = tokenPermissions.filter(p => user.permissions.includes(p));
|
|
86
|
+
}
|
|
87
|
+
const token = {
|
|
88
|
+
token: `bsb_${(0, crypto_1.randomBytes)(32).toString('hex')}`,
|
|
89
|
+
userId,
|
|
90
|
+
name: label,
|
|
91
|
+
permissions: perms,
|
|
92
|
+
createdAt: new Date().toISOString(),
|
|
93
|
+
expiresAt,
|
|
94
|
+
};
|
|
95
|
+
await this.db.createToken(obs, token);
|
|
96
|
+
return token;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve a bearer token string to the owning user.
|
|
100
|
+
*
|
|
101
|
+
* Returns null if the token is invalid, expired, or the user is inactive.
|
|
102
|
+
* `effectivePermissions` is the intersection of user and token permissions.
|
|
103
|
+
* If the token has no explicit permissions, user permissions are inherited.
|
|
104
|
+
*/
|
|
105
|
+
async resolveToken(obs, tokenString) {
|
|
106
|
+
const token = await this.db.getToken(obs, tokenString);
|
|
107
|
+
if (!token)
|
|
108
|
+
return null;
|
|
109
|
+
// Check expiration
|
|
110
|
+
if (token.expiresAt && new Date(token.expiresAt) < new Date()) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const user = await this.db.getUser(obs, token.userId);
|
|
114
|
+
if (!user || !user.active)
|
|
115
|
+
return null;
|
|
116
|
+
// Compute effective permissions: intersection of user and token
|
|
117
|
+
let effectivePermissions;
|
|
118
|
+
if (token.permissions && token.permissions.length > 0) {
|
|
119
|
+
// Token has explicit scope -- intersect with current user permissions
|
|
120
|
+
effectivePermissions = token.permissions.filter(p => user.permissions.includes(p));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Token inherits all user permissions
|
|
124
|
+
effectivePermissions = [...user.permissions];
|
|
125
|
+
}
|
|
126
|
+
return { userId: user.id, user, token, effectivePermissions };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get all tokens belonging to a user.
|
|
130
|
+
*/
|
|
131
|
+
async getTokensForUser(obs, userId) {
|
|
132
|
+
return this.db.getTokensForUser(obs, userId);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Revoke (delete) a specific token.
|
|
136
|
+
*/
|
|
137
|
+
async revokeToken(obs, tokenString) {
|
|
138
|
+
return this.db.deleteToken(obs, tokenString);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Revoke all tokens belonging to a user.
|
|
142
|
+
*/
|
|
143
|
+
async revokeAllTokensForUser(obs, userId) {
|
|
144
|
+
return this.db.deleteTokensForUser(obs, userId);
|
|
145
|
+
}
|
|
146
|
+
// ============================================================================
|
|
147
|
+
// Permission checking (pure logic -- no storage access)
|
|
148
|
+
// ============================================================================
|
|
149
|
+
/**
|
|
150
|
+
* Check if the resolved auth has a specific user-level permission.
|
|
151
|
+
* Uses `effectivePermissions` (intersection of user + token perms).
|
|
152
|
+
*/
|
|
153
|
+
hasUserPermission(auth, required) {
|
|
154
|
+
return auth.effectivePermissions.includes(required);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if a user has the required resource-level permission on a package.
|
|
158
|
+
*
|
|
159
|
+
* Resolution order:
|
|
160
|
+
* 1. Package-level permissions (if any) -- explicit grant wins
|
|
161
|
+
* 2. Org-level membership -- inherited from org members list
|
|
162
|
+
* 3. Deny
|
|
163
|
+
*
|
|
164
|
+
* The caller must also separately check that the auth token has the
|
|
165
|
+
* user-level 'write' permission for write operations.
|
|
166
|
+
*/
|
|
167
|
+
hasResourcePermission(userId, requiredLevel, packagePermissions, orgMembers) {
|
|
168
|
+
// 1. Check package-level permissions first
|
|
169
|
+
if (packagePermissions && packagePermissions.length > 0) {
|
|
170
|
+
const pkgPerm = packagePermissions.find(p => p.userId === userId);
|
|
171
|
+
if (pkgPerm) {
|
|
172
|
+
return this.resourcePermSatisfies(pkgPerm.permission, requiredLevel);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// 2. Fall back to org membership
|
|
176
|
+
if (orgMembers && orgMembers.length > 0) {
|
|
177
|
+
const orgMember = orgMembers.find(m => m.userId === userId);
|
|
178
|
+
if (orgMember) {
|
|
179
|
+
return this.resourcePermSatisfies(orgMember.permission, requiredLevel);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// 3. No permission found
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check if the granted resource permission satisfies the required level.
|
|
187
|
+
* 'write' satisfies both 'read' and 'write'.
|
|
188
|
+
* 'read' only satisfies 'read'.
|
|
189
|
+
*/
|
|
190
|
+
resourcePermSatisfies(granted, required) {
|
|
191
|
+
if (granted === 'write')
|
|
192
|
+
return true; // write implies read
|
|
193
|
+
return required === 'read';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
exports.AuthManager = AuthManager;
|
|
197
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/plugins/service-bsb-registry/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based database implementation for BSB Registry.
|
|
3
|
+
*
|
|
4
|
+
* Layout on disk:
|
|
5
|
+
* <dataDir>/
|
|
6
|
+
* orgs/
|
|
7
|
+
* <orgId>.json Organization metadata (includes members)
|
|
8
|
+
* plugins/
|
|
9
|
+
* <org>/
|
|
10
|
+
* <name>/
|
|
11
|
+
* <version>.json Full RegistryEntry for each version
|
|
12
|
+
* users.json User[] - all registered users
|
|
13
|
+
* tokens.json AuthToken[] - all auth tokens
|
|
14
|
+
*/
|
|
15
|
+
import type { Observable } from '@bsb/base';
|
|
16
|
+
import type { RegistryDB } from './index';
|
|
17
|
+
import type { RegistryEntry, ListQuery, SearchQuery, RegistryStats, VersionInfo, Organization, OrgMember, ResourcePermission, User, AuthToken } from '../types';
|
|
18
|
+
export declare class FileDB implements RegistryDB {
|
|
19
|
+
private readonly dataDir;
|
|
20
|
+
private readonly pluginsDir;
|
|
21
|
+
private readonly orgsDir;
|
|
22
|
+
private readonly usersFile;
|
|
23
|
+
private readonly tokensFile;
|
|
24
|
+
constructor(dataDir: string);
|
|
25
|
+
init(obs: Observable): Promise<void>;
|
|
26
|
+
dispose(): Promise<void>;
|
|
27
|
+
versionExists(obs: Observable, org: string, name: string, version: string): Promise<boolean>;
|
|
28
|
+
insert(obs: Observable, entry: RegistryEntry): Promise<void>;
|
|
29
|
+
get(obs: Observable, org: string, name: string, version?: string): Promise<RegistryEntry | null>;
|
|
30
|
+
delete(obs: Observable, org: string, name: string, version?: string): Promise<void>;
|
|
31
|
+
list(obs: Observable, query: ListQuery): Promise<{
|
|
32
|
+
results: RegistryEntry[];
|
|
33
|
+
total: number;
|
|
34
|
+
}>;
|
|
35
|
+
search(obs: Observable, query: SearchQuery): Promise<{
|
|
36
|
+
results: RegistryEntry[];
|
|
37
|
+
total: number;
|
|
38
|
+
}>;
|
|
39
|
+
getVersions(obs: Observable, org: string, name: string, majorMinor?: string): Promise<VersionInfo[]>;
|
|
40
|
+
getStats(obs: Observable): Promise<RegistryStats>;
|
|
41
|
+
getOrganization(obs: Observable, orgId: string): Promise<Organization | null>;
|
|
42
|
+
createOrganization(obs: Observable, orgId: string, displayName: string, visibility: 'public' | 'private'): Promise<Organization>;
|
|
43
|
+
setOrgMember(obs: Observable, orgId: string, userId: string, permission: ResourcePermission): Promise<void>;
|
|
44
|
+
removeOrgMember(obs: Observable, orgId: string, userId: string): Promise<void>;
|
|
45
|
+
getOrgMembers(obs: Observable, orgId: string): Promise<OrgMember[]>;
|
|
46
|
+
getUser(obs: Observable, userId: string): Promise<User | null>;
|
|
47
|
+
getUserByEmail(obs: Observable, email: string): Promise<User | null>;
|
|
48
|
+
listUsers(obs: Observable): Promise<User[]>;
|
|
49
|
+
createUser(obs: Observable, user: User): Promise<void>;
|
|
50
|
+
updateUser(obs: Observable, userId: string, updates: Partial<Pick<User, 'name' | 'email' | 'active' | 'permissions'>>): Promise<User | null>;
|
|
51
|
+
getToken(obs: Observable, tokenString: string): Promise<AuthToken | null>;
|
|
52
|
+
getTokensForUser(obs: Observable, userId: string): Promise<AuthToken[]>;
|
|
53
|
+
createToken(obs: Observable, token: AuthToken): Promise<void>;
|
|
54
|
+
deleteToken(obs: Observable, tokenString: string): Promise<boolean>;
|
|
55
|
+
deleteTokensForUser(obs: Observable, userId: string): Promise<number>;
|
|
56
|
+
private pluginDir;
|
|
57
|
+
private versionPath;
|
|
58
|
+
/** List version JSON files in a plugin directory. Returns filenames (no path). */
|
|
59
|
+
private listVersionFiles;
|
|
60
|
+
/** Read a single version entry. Returns null if file does not exist. */
|
|
61
|
+
private readVersion;
|
|
62
|
+
/** Read every version entry for a plugin. */
|
|
63
|
+
private readAllVersions;
|
|
64
|
+
/** Walk every org/plugin directory and return the latest entry of each plugin. */
|
|
65
|
+
private allLatestEntries;
|
|
66
|
+
/** Pick the entry with the most recent publishedAt. */
|
|
67
|
+
private latestEntry;
|
|
68
|
+
/** Remove a directory if it exists and is empty. */
|
|
69
|
+
private rmdir;
|
|
70
|
+
private readJson;
|
|
71
|
+
private writeJson;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../../src/plugins/service-bsb-registry/db/file.ts"],"names":[],"mappings":"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"}
|