@objectstack/plugin-sharing 6.8.1 → 7.0.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @objectstack/plugin-sharing@6.8.1 build /home/runner/work/framework/framework/packages/plugins/plugin-sharing
2
+ > @objectstack/plugin-sharing@7.0.0 build /home/runner/work/framework/framework/packages/plugins/plugin-sharing
3
3
  > tsup --config ../../../tsup.config.ts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- ESM dist/index.mjs 31.83 KB
14
- ESM dist/index.mjs.map 70.78 KB
15
- ESM ⚡️ Build success in 155ms
16
- CJS dist/index.js 33.33 KB
17
- CJS dist/index.js.map 70.80 KB
18
- CJS ⚡️ Build success in 159ms
13
+ CJS dist/index.js 50.56 KB
14
+ CJS dist/index.js.map 110.16 KB
15
+ CJS ⚡️ Build success in 188ms
16
+ ESM dist/index.mjs 48.89 KB
17
+ ESM dist/index.mjs.map 110.16 KB
18
+ ESM ⚡️ Build success in 191ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 19261ms
21
- DTS dist/index.d.mts 11.90 KB
22
- DTS dist/index.d.ts 11.90 KB
20
+ DTS ⚡️ Build success in 22194ms
21
+ DTS dist/index.d.mts 15.66 KB
22
+ DTS dist/index.d.ts 15.66 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @objectstack/plugin-sharing
2
2
 
3
+ ## 7.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [74470ad]
8
+ - Updated dependencies [d29617e]
9
+ - Updated dependencies [dc72172]
10
+ - Updated dependencies [d29617e]
11
+ - Updated dependencies [010757b]
12
+ - Updated dependencies [257954d]
13
+ - @objectstack/spec@7.0.0
14
+ - @objectstack/platform-objects@7.0.0
15
+ - @objectstack/core@7.0.0
16
+ - @objectstack/objectql@7.0.0
17
+
18
+ ## 6.9.0
19
+
20
+ ### Patch Changes
21
+
22
+ - @objectstack/spec@6.9.0
23
+ - @objectstack/core@6.9.0
24
+ - @objectstack/objectql@6.9.0
25
+ - @objectstack/platform-objects@6.9.0
26
+
3
27
  ## 6.8.1
4
28
 
5
29
  ### Patch Changes
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 };