@objectstack/plugin-sharing 6.8.1 → 6.9.0
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +9 -0
- package/dist/index.d.mts +82 -4
- package/dist/index.d.ts +82 -4
- package/dist/index.js +466 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +464 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +18 -1
- package/src/share-link-routes.ts +266 -0
- package/src/share-link-service.test.ts +166 -0
- package/src/share-link-service.ts +373 -0
- package/src/sharing-plugin.ts +54 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @objectstack/plugin-sharing@6.
|
|
2
|
+
> @objectstack/plugin-sharing@6.9.0 build /home/runner/work/framework/framework/packages/plugins/plugin-sharing
|
|
3
3
|
> tsup --config ../../../tsup.config.ts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
14
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[
|
|
15
|
-
[32mESM[39m ⚡️ Build success in
|
|
16
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
17
|
-
[32mCJS[39m [1mdist/index.js.map [22m[
|
|
18
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m48.89 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m110.16 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 249ms
|
|
16
|
+
[32mCJS[39m [1mdist/index.js [22m[32m50.56 KB[39m
|
|
17
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m110.16 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 258ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 21619ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m15.66 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m15.66 KB[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { SysRecordShare, SysSharingRule } from '@objectstack/platform-objects/security';
|
|
1
|
+
export { SysRecordShare, SysShareLink, SysSharingRule } from '@objectstack/platform-objects/security';
|
|
2
2
|
export { SysDepartment, SysDepartmentMember } from '@objectstack/platform-objects/identity';
|
|
3
|
-
import { ISharingService, SharingExecutionContext, GrantShareInput, RecordShare, ISharingRuleService, DefineSharingRuleInput, SharingRuleRow, SharingRuleEvaluationResult, ITeamGraphService, IDepartmentGraphService } from '@objectstack/spec/contracts';
|
|
4
|
-
export { DefineSharingRuleInput, GrantShareInput, IDepartmentGraphService, ISharingRuleService, ISharingService, ITeamGraphService, RecordShare, ShareAccessLevel, ShareRecipientType, ShareSource, SharingExecutionContext, SharingRuleEvaluationResult, SharingRuleRecipientType, SharingRuleRow } from '@objectstack/spec/contracts';
|
|
3
|
+
import { ISharingService, SharingExecutionContext, GrantShareInput, RecordShare, ISharingRuleService, DefineSharingRuleInput, SharingRuleRow, SharingRuleEvaluationResult, IShareLinkService, CreateShareLinkInput, ShareLinkExecutionContext, ShareLink, ListShareLinksFilter, ResolveShareLinkResult, IHttpRequest, IHttpServer, ITeamGraphService, IDepartmentGraphService } from '@objectstack/spec/contracts';
|
|
4
|
+
export { CreateShareLinkInput, DefineSharingRuleInput, GrantShareInput, IDepartmentGraphService, IShareLinkService, ISharingRuleService, ISharingService, ITeamGraphService, ListShareLinksFilter, RecordShare, ResolveShareLinkResult, SHARE_LINK_SERVICE, ShareAccessLevel, ShareLink, ShareLinkAudience, ShareLinkExecutionContext, ShareLinkPermission, ShareRecipientType, ShareSource, SharingExecutionContext, SharingRuleEvaluationResult, SharingRuleRecipientType, SharingRuleRow } from '@objectstack/spec/contracts';
|
|
5
5
|
import { Plugin, PluginContext } from '@objectstack/core';
|
|
6
6
|
import { EngineMiddleware } from '@objectstack/objectql';
|
|
7
7
|
|
|
@@ -98,6 +98,72 @@ declare class SharingRuleService implements ISharingRuleService {
|
|
|
98
98
|
private purgeRuleGrants;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
interface ShareLinkServiceOptions {
|
|
102
|
+
engine: SharingEngine;
|
|
103
|
+
/** Override the default SHA-256 hasher with argon2 / bcrypt for production. */
|
|
104
|
+
hashPassword?: (plain: string) => Promise<string>;
|
|
105
|
+
/** Companion verifier — must accept hashes produced by `hashPassword`. */
|
|
106
|
+
verifyPassword?: (plain: string, hash: string) => Promise<boolean>;
|
|
107
|
+
/**
|
|
108
|
+
* Bypass the per-object opt-in check (useful when the schema scan is
|
|
109
|
+
* happening after `start`). When omitted, calls against an object
|
|
110
|
+
* without `publicSharing.enabled=true` are rejected with 422.
|
|
111
|
+
*/
|
|
112
|
+
permissive?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Default `IShareLinkService` implementation.
|
|
116
|
+
*
|
|
117
|
+
* Persists every link in `sys_share_link`. The companion REST routes
|
|
118
|
+
* (`registerShareLinkRoutes`) thin-wrap the service; the public
|
|
119
|
+
* `/api/v1/share-links/:token` route resolves and re-injects the
|
|
120
|
+
* "share-link principal" into the execution context so the standard
|
|
121
|
+
* data middleware can authorise the downstream read.
|
|
122
|
+
*/
|
|
123
|
+
declare class ShareLinkService implements IShareLinkService {
|
|
124
|
+
private readonly engine;
|
|
125
|
+
private readonly permissive;
|
|
126
|
+
private readonly hashPassword;
|
|
127
|
+
private readonly verifyPassword;
|
|
128
|
+
constructor(opts: ShareLinkServiceOptions);
|
|
129
|
+
createLink(input: CreateShareLinkInput, context: ShareLinkExecutionContext): Promise<ShareLink>;
|
|
130
|
+
revokeLink(idOrToken: string, _context: ShareLinkExecutionContext): Promise<void>;
|
|
131
|
+
listLinks(filter: ListShareLinksFilter, context: ShareLinkExecutionContext): Promise<ShareLink[]>;
|
|
132
|
+
resolveToken(token: string, probe?: {
|
|
133
|
+
signedInUserId?: string;
|
|
134
|
+
recipientEmail?: string;
|
|
135
|
+
providedPassword?: string;
|
|
136
|
+
}): Promise<ResolveShareLinkResult | null>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* REST surface for ShareLinkService.
|
|
141
|
+
*
|
|
142
|
+
* POST /api/v1/share-links → create a link
|
|
143
|
+
* GET /api/v1/share-links → list links (?object, ?recordId, ?includeRevoked)
|
|
144
|
+
* DELETE /api/v1/share-links/:idOrToken → revoke
|
|
145
|
+
* GET /api/v1/share-links/:token/resolve → resolve token, returns { record, link, redactFields }
|
|
146
|
+
*
|
|
147
|
+
* The resolve route is intentionally public — it's the only endpoint
|
|
148
|
+
* holders of a token need. It does:
|
|
149
|
+
*
|
|
150
|
+
* 1. Look up the row by token (via ShareLinkService.resolveToken,
|
|
151
|
+
* which gates audience / expiry / password and stamps usage).
|
|
152
|
+
* 2. Fetch the underlying record with a SYSTEM context (so the read
|
|
153
|
+
* bypasses normal RLS — the token IS the authorisation).
|
|
154
|
+
* 3. Strip `redactFields` from the record before returning.
|
|
155
|
+
*
|
|
156
|
+
* For browser-rendered share pages, the front-end calls this endpoint
|
|
157
|
+
* and renders the response read-only.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
interface ShareLinkRoutesOptions {
|
|
161
|
+
basePath?: string;
|
|
162
|
+
/** Read caller identity for authenticated routes. */
|
|
163
|
+
contextFromRequest?: (req: IHttpRequest) => ShareLinkExecutionContext;
|
|
164
|
+
}
|
|
165
|
+
declare function registerShareLinkRoutes(http: IHttpServer, service: ShareLinkService, engine: SharingEngine, opts?: ShareLinkRoutesOptions): void;
|
|
166
|
+
|
|
101
167
|
type Cache = {
|
|
102
168
|
expandUsers?: Map<string, string[]>;
|
|
103
169
|
expandRole?: Map<string, string[]>;
|
|
@@ -237,6 +303,17 @@ interface SharingPluginOptions {
|
|
|
237
303
|
* via env var without rebuilding.
|
|
238
304
|
*/
|
|
239
305
|
enforce?: boolean;
|
|
306
|
+
/**
|
|
307
|
+
* Disable the public share-link REST routes. The `IShareLinkService`
|
|
308
|
+
* is always registered (other services may depend on it); only the
|
|
309
|
+
* HTTP surface is suppressed.
|
|
310
|
+
*/
|
|
311
|
+
registerShareLinkRoutes?: boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Base path for the share-link REST surface. Defaults to
|
|
314
|
+
* `/api/v1/share-links`.
|
|
315
|
+
*/
|
|
316
|
+
shareLinkBasePath?: string;
|
|
240
317
|
}
|
|
241
318
|
/**
|
|
242
319
|
* SharingServicePlugin — registers `sys_record_share`, the `sharing`
|
|
@@ -276,6 +353,7 @@ declare class SharingServicePlugin implements Plugin {
|
|
|
276
353
|
private readonly options;
|
|
277
354
|
private service?;
|
|
278
355
|
private ruleService?;
|
|
356
|
+
private linkService?;
|
|
279
357
|
constructor(options?: SharingPluginOptions);
|
|
280
358
|
init(ctx: PluginContext): Promise<void>;
|
|
281
359
|
start(ctx: PluginContext): Promise<void>;
|
|
@@ -287,4 +365,4 @@ declare class SharingServicePlugin implements Plugin {
|
|
|
287
365
|
*/
|
|
288
366
|
declare function buildSharingMiddleware(service: SharingService): EngineMiddleware;
|
|
289
367
|
|
|
290
|
-
export { type DepartmentGraphOptions, DepartmentGraphService, SHARING_RULE_HOOK_PACKAGE, type SharingEngine, type SharingPluginOptions, SharingRuleService, type SharingRuleServiceOptions, SharingService, type SharingServiceOptions, SharingServicePlugin, type TeamGraphOptions, TeamGraphService, bindRuleHooks, buildSharingMiddleware, expandPrincipal, unbindAllRuleHooks };
|
|
368
|
+
export { type DepartmentGraphOptions, DepartmentGraphService, SHARING_RULE_HOOK_PACKAGE, type ShareLinkRoutesOptions, ShareLinkService, type ShareLinkServiceOptions, type SharingEngine, type SharingPluginOptions, SharingRuleService, type SharingRuleServiceOptions, SharingService, type SharingServiceOptions, SharingServicePlugin, type TeamGraphOptions, TeamGraphService, bindRuleHooks, buildSharingMiddleware, expandPrincipal, registerShareLinkRoutes, unbindAllRuleHooks };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { SysRecordShare, SysSharingRule } from '@objectstack/platform-objects/security';
|
|
1
|
+
export { SysRecordShare, SysShareLink, SysSharingRule } from '@objectstack/platform-objects/security';
|
|
2
2
|
export { SysDepartment, SysDepartmentMember } from '@objectstack/platform-objects/identity';
|
|
3
|
-
import { ISharingService, SharingExecutionContext, GrantShareInput, RecordShare, ISharingRuleService, DefineSharingRuleInput, SharingRuleRow, SharingRuleEvaluationResult, ITeamGraphService, IDepartmentGraphService } from '@objectstack/spec/contracts';
|
|
4
|
-
export { DefineSharingRuleInput, GrantShareInput, IDepartmentGraphService, ISharingRuleService, ISharingService, ITeamGraphService, RecordShare, ShareAccessLevel, ShareRecipientType, ShareSource, SharingExecutionContext, SharingRuleEvaluationResult, SharingRuleRecipientType, SharingRuleRow } from '@objectstack/spec/contracts';
|
|
3
|
+
import { ISharingService, SharingExecutionContext, GrantShareInput, RecordShare, ISharingRuleService, DefineSharingRuleInput, SharingRuleRow, SharingRuleEvaluationResult, IShareLinkService, CreateShareLinkInput, ShareLinkExecutionContext, ShareLink, ListShareLinksFilter, ResolveShareLinkResult, IHttpRequest, IHttpServer, ITeamGraphService, IDepartmentGraphService } from '@objectstack/spec/contracts';
|
|
4
|
+
export { CreateShareLinkInput, DefineSharingRuleInput, GrantShareInput, IDepartmentGraphService, IShareLinkService, ISharingRuleService, ISharingService, ITeamGraphService, ListShareLinksFilter, RecordShare, ResolveShareLinkResult, SHARE_LINK_SERVICE, ShareAccessLevel, ShareLink, ShareLinkAudience, ShareLinkExecutionContext, ShareLinkPermission, ShareRecipientType, ShareSource, SharingExecutionContext, SharingRuleEvaluationResult, SharingRuleRecipientType, SharingRuleRow } from '@objectstack/spec/contracts';
|
|
5
5
|
import { Plugin, PluginContext } from '@objectstack/core';
|
|
6
6
|
import { EngineMiddleware } from '@objectstack/objectql';
|
|
7
7
|
|
|
@@ -98,6 +98,72 @@ declare class SharingRuleService implements ISharingRuleService {
|
|
|
98
98
|
private purgeRuleGrants;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
interface ShareLinkServiceOptions {
|
|
102
|
+
engine: SharingEngine;
|
|
103
|
+
/** Override the default SHA-256 hasher with argon2 / bcrypt for production. */
|
|
104
|
+
hashPassword?: (plain: string) => Promise<string>;
|
|
105
|
+
/** Companion verifier — must accept hashes produced by `hashPassword`. */
|
|
106
|
+
verifyPassword?: (plain: string, hash: string) => Promise<boolean>;
|
|
107
|
+
/**
|
|
108
|
+
* Bypass the per-object opt-in check (useful when the schema scan is
|
|
109
|
+
* happening after `start`). When omitted, calls against an object
|
|
110
|
+
* without `publicSharing.enabled=true` are rejected with 422.
|
|
111
|
+
*/
|
|
112
|
+
permissive?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Default `IShareLinkService` implementation.
|
|
116
|
+
*
|
|
117
|
+
* Persists every link in `sys_share_link`. The companion REST routes
|
|
118
|
+
* (`registerShareLinkRoutes`) thin-wrap the service; the public
|
|
119
|
+
* `/api/v1/share-links/:token` route resolves and re-injects the
|
|
120
|
+
* "share-link principal" into the execution context so the standard
|
|
121
|
+
* data middleware can authorise the downstream read.
|
|
122
|
+
*/
|
|
123
|
+
declare class ShareLinkService implements IShareLinkService {
|
|
124
|
+
private readonly engine;
|
|
125
|
+
private readonly permissive;
|
|
126
|
+
private readonly hashPassword;
|
|
127
|
+
private readonly verifyPassword;
|
|
128
|
+
constructor(opts: ShareLinkServiceOptions);
|
|
129
|
+
createLink(input: CreateShareLinkInput, context: ShareLinkExecutionContext): Promise<ShareLink>;
|
|
130
|
+
revokeLink(idOrToken: string, _context: ShareLinkExecutionContext): Promise<void>;
|
|
131
|
+
listLinks(filter: ListShareLinksFilter, context: ShareLinkExecutionContext): Promise<ShareLink[]>;
|
|
132
|
+
resolveToken(token: string, probe?: {
|
|
133
|
+
signedInUserId?: string;
|
|
134
|
+
recipientEmail?: string;
|
|
135
|
+
providedPassword?: string;
|
|
136
|
+
}): Promise<ResolveShareLinkResult | null>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* REST surface for ShareLinkService.
|
|
141
|
+
*
|
|
142
|
+
* POST /api/v1/share-links → create a link
|
|
143
|
+
* GET /api/v1/share-links → list links (?object, ?recordId, ?includeRevoked)
|
|
144
|
+
* DELETE /api/v1/share-links/:idOrToken → revoke
|
|
145
|
+
* GET /api/v1/share-links/:token/resolve → resolve token, returns { record, link, redactFields }
|
|
146
|
+
*
|
|
147
|
+
* The resolve route is intentionally public — it's the only endpoint
|
|
148
|
+
* holders of a token need. It does:
|
|
149
|
+
*
|
|
150
|
+
* 1. Look up the row by token (via ShareLinkService.resolveToken,
|
|
151
|
+
* which gates audience / expiry / password and stamps usage).
|
|
152
|
+
* 2. Fetch the underlying record with a SYSTEM context (so the read
|
|
153
|
+
* bypasses normal RLS — the token IS the authorisation).
|
|
154
|
+
* 3. Strip `redactFields` from the record before returning.
|
|
155
|
+
*
|
|
156
|
+
* For browser-rendered share pages, the front-end calls this endpoint
|
|
157
|
+
* and renders the response read-only.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
interface ShareLinkRoutesOptions {
|
|
161
|
+
basePath?: string;
|
|
162
|
+
/** Read caller identity for authenticated routes. */
|
|
163
|
+
contextFromRequest?: (req: IHttpRequest) => ShareLinkExecutionContext;
|
|
164
|
+
}
|
|
165
|
+
declare function registerShareLinkRoutes(http: IHttpServer, service: ShareLinkService, engine: SharingEngine, opts?: ShareLinkRoutesOptions): void;
|
|
166
|
+
|
|
101
167
|
type Cache = {
|
|
102
168
|
expandUsers?: Map<string, string[]>;
|
|
103
169
|
expandRole?: Map<string, string[]>;
|
|
@@ -237,6 +303,17 @@ interface SharingPluginOptions {
|
|
|
237
303
|
* via env var without rebuilding.
|
|
238
304
|
*/
|
|
239
305
|
enforce?: boolean;
|
|
306
|
+
/**
|
|
307
|
+
* Disable the public share-link REST routes. The `IShareLinkService`
|
|
308
|
+
* is always registered (other services may depend on it); only the
|
|
309
|
+
* HTTP surface is suppressed.
|
|
310
|
+
*/
|
|
311
|
+
registerShareLinkRoutes?: boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Base path for the share-link REST surface. Defaults to
|
|
314
|
+
* `/api/v1/share-links`.
|
|
315
|
+
*/
|
|
316
|
+
shareLinkBasePath?: string;
|
|
240
317
|
}
|
|
241
318
|
/**
|
|
242
319
|
* SharingServicePlugin — registers `sys_record_share`, the `sharing`
|
|
@@ -276,6 +353,7 @@ declare class SharingServicePlugin implements Plugin {
|
|
|
276
353
|
private readonly options;
|
|
277
354
|
private service?;
|
|
278
355
|
private ruleService?;
|
|
356
|
+
private linkService?;
|
|
279
357
|
constructor(options?: SharingPluginOptions);
|
|
280
358
|
init(ctx: PluginContext): Promise<void>;
|
|
281
359
|
start(ctx: PluginContext): Promise<void>;
|
|
@@ -287,4 +365,4 @@ declare class SharingServicePlugin implements Plugin {
|
|
|
287
365
|
*/
|
|
288
366
|
declare function buildSharingMiddleware(service: SharingService): EngineMiddleware;
|
|
289
367
|
|
|
290
|
-
export { type DepartmentGraphOptions, DepartmentGraphService, SHARING_RULE_HOOK_PACKAGE, type SharingEngine, type SharingPluginOptions, SharingRuleService, type SharingRuleServiceOptions, SharingService, type SharingServiceOptions, SharingServicePlugin, type TeamGraphOptions, TeamGraphService, bindRuleHooks, buildSharingMiddleware, expandPrincipal, unbindAllRuleHooks };
|
|
368
|
+
export { type DepartmentGraphOptions, DepartmentGraphService, SHARING_RULE_HOOK_PACKAGE, type ShareLinkRoutesOptions, ShareLinkService, type ShareLinkServiceOptions, type SharingEngine, type SharingPluginOptions, SharingRuleService, type SharingRuleServiceOptions, SharingService, type SharingServiceOptions, SharingServicePlugin, type TeamGraphOptions, TeamGraphService, bindRuleHooks, buildSharingMiddleware, expandPrincipal, registerShareLinkRoutes, unbindAllRuleHooks };
|