@objectstack/plugin-sharing 9.9.1 → 9.11.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/translations/en.objects.generated.ts","../src/translations/zh-CN.objects.generated.ts","../src/translations/ja-JP.objects.generated.ts","../src/translations/es-ES.objects.generated.ts","../src/translations/index.ts","../src/index.ts","../src/objects/sys-record-share.object.ts","../src/objects/sys-sharing-rule.object.ts","../src/objects/sys-share-link.object.ts","../src/sharing-service.ts","../src/team-graph.ts","../src/department-graph.ts","../src/sharing-rule-service.ts","../src/share-link-service.ts","../src/share-link-routes.ts","../src/rule-hooks.ts","../src/sharing-plugin.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'en'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const enObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"Record Share\",\n pluralLabel: \"Record Shares\",\n description: \"Per-record sharing grant — extends OWD with explicit access\",\n fields: {\n id: {\n label: \"Share ID\"\n },\n object_name: {\n label: \"Object\",\n help: \"Short object name of the shared record\"\n },\n record_id: {\n label: \"Record\",\n help: \"Primary key of the shared record within object_name\"\n },\n recipient_type: {\n label: \"Recipient Type\",\n help: \"Kind of principal that holds the grant\",\n options: {\n user: \"user\",\n group: \"group\",\n role: \"role\",\n role_and_subordinates: \"role_and_subordinates\",\n guest: \"guest\"\n }\n },\n recipient_id: {\n label: \"Recipient\",\n help: \"ID of the user/group/role that receives access\"\n },\n access_level: {\n label: \"Access Level\",\n help: \"What the recipient can do — read | edit | full (transfer/share/delete)\",\n options: {\n read: \"read\",\n edit: \"edit\",\n full: \"full\"\n }\n },\n source: {\n label: \"Source\",\n help: \"Why this grant exists — used by the rule evaluator to reconcile\",\n options: {\n manual: \"manual\",\n rule: \"rule\",\n team: \"team\",\n inherited: \"inherited\"\n }\n },\n source_id: {\n label: \"Source ID\",\n help: \"Rule name / team id when source != manual\"\n },\n granted_by: {\n label: \"Granted By\",\n help: \"User that created the grant (manual only)\"\n },\n reason: {\n label: \"Reason\",\n help: \"Optional free-text explanation surfaced to the recipient\"\n },\n created_at: {\n label: \"Created At\"\n },\n updated_at: {\n label: \"Updated At\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"Granted to Me\"\n },\n granted_by_me: {\n label: \"Granted by Me\"\n },\n by_object: {\n label: \"By Object\"\n },\n manual_grants: {\n label: \"Manual Grants\"\n },\n rule_grants: {\n label: \"Rule Grants\"\n },\n all_shares: {\n label: \"All\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"Sharing Rule\",\n pluralLabel: \"Sharing Rules\",\n description: \"Declarative sharing rule that auto-materialises sys_record_share grants. Authored via defineSharingRule() in code or the Studio criteria builder.\",\n fields: {\n id: {\n label: \"Rule ID\"\n },\n organization_id: {\n label: \"Organization\",\n help: \"Tenant that owns this rule; null = global\"\n },\n name: {\n label: \"Name\",\n help: \"Unique snake_case rule name\"\n },\n label: {\n label: \"Display Label\"\n },\n description: {\n label: \"Description\"\n },\n object_name: {\n label: \"Object\",\n help: \"Short object name (e.g. opportunity, account)\"\n },\n criteria_json: {\n label: \"Criteria (FilterCondition JSON)\",\n help: \"JSON FilterCondition matched against records of object_name. Empty = match all.\"\n },\n recipient_type: {\n label: \"Recipient Type\",\n help: \"Kind of principal that receives access — expanded to user grants at evaluation time. `department` walks the parent_department_id tree; `team` is flat (better-auth).\",\n options: {\n user: \"user\",\n team: \"team\",\n department: \"department\",\n role: \"role\",\n queue: \"queue\"\n }\n },\n recipient_id: {\n label: \"Recipient\",\n help: \"department id / team id / role name / queue name / user id depending on recipient_type\"\n },\n access_level: {\n label: \"Access Level\",\n options: {\n read: \"read\",\n edit: \"edit\",\n full: \"full\"\n }\n },\n active: {\n label: \"Active\",\n help: \"Only active rules participate in lifecycle evaluation\"\n },\n created_at: {\n label: \"Created At\"\n },\n updated_at: {\n label: \"Updated At\"\n }\n },\n _views: {\n active: {\n label: \"Active\"\n },\n inactive: {\n label: \"Inactive\"\n },\n by_object: {\n label: \"By Object\"\n },\n all_rules: {\n label: \"All\"\n }\n }\n },\n sys_share_link: {\n label: \"Share Link\",\n pluralLabel: \"Share Links\",\n description: \"Opaque capability token granting access to a single record. Notion/Figma-style public link sharing.\",\n fields: {\n id: {\n label: \"Link ID\"\n },\n token: {\n label: \"Token\",\n help: \"Opaque URL-safe random token (≥ 22 chars). The only secret in this row.\"\n },\n object_name: {\n label: \"Object\",\n help: \"Short object name of the shared record (e.g. ai_conversation, contracts_contract)\"\n },\n record_id: {\n label: \"Record\",\n help: \"Primary key of the shared record within object_name\"\n },\n permission: {\n label: \"Permission\",\n help: \"What the link holder can do with the record\",\n options: {\n view: \"View\",\n comment: \"Comment\",\n edit: \"Edit\"\n }\n },\n audience: {\n label: \"Audience\",\n help: \"Gating layer applied on top of the token check\",\n options: {\n public: \"Public (indexable)\",\n link_only: \"Anyone with the link\",\n signed_in: \"Signed-in users\",\n email: \"Specific emails\"\n }\n },\n expires_at: {\n label: \"Expires At\",\n help: \"When set, resolveToken returns null after this timestamp\"\n },\n email_allowlist: {\n label: \"Email Allowlist\",\n help: \"Lowercased addresses checked when audience=email\"\n },\n password_hash: {\n label: \"Password Hash\",\n help: \"Argon2/bcrypt hash. When set, the UI prompts for a password before rendering.\"\n },\n redact_fields: {\n label: \"Per-Link Redactions\",\n help: \"Extra fields stripped from the response, on top of the object-default set\"\n },\n label: {\n label: \"Label\",\n help: \"Free-text shown in the share dialog (e.g. \\\"ACME Q3 contract\\\")\"\n },\n revoked_at: {\n label: \"Revoked At\",\n help: \"When set, the link is permanently disabled\"\n },\n created_by: {\n label: \"Created By\",\n help: \"Issuer of the link\"\n },\n created_at: {\n label: \"Created At\"\n },\n last_used_at: {\n label: \"Last Used At\",\n help: \"Stamped by resolveToken; used by the dashboard to highlight active links\"\n },\n use_count: {\n label: \"Use Count\",\n help: \"Incremented by resolveToken on every successful resolution\"\n }\n },\n _views: {\n active_links: {\n label: \"Active\"\n },\n by_me: {\n label: \"Created by Me\"\n },\n revoked: {\n label: \"Revoked\"\n },\n all_links: {\n label: \"All\"\n }\n }\n }\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'zh-CN'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const zhCNObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"记录共享\",\n pluralLabel: \"记录共享\",\n description: \"按记录粒度的共享授权——在 OWD 基础上提供显式访问\",\n fields: {\n id: {\n label: \"共享 ID\"\n },\n object_name: {\n label: \"对象\",\n help: \"被共享记录的短对象名\"\n },\n record_id: {\n label: \"记录\",\n help: \"object_name 对应对象内该共享记录的主键\"\n },\n recipient_type: {\n label: \"接收方类型\",\n help: \"持有该授权的主体类型\",\n options: {\n user: \"用户\",\n group: \"组\",\n role: \"角色\",\n role_and_subordinates: \"角色及下级\",\n guest: \"访客\"\n }\n },\n recipient_id: {\n label: \"接收方\",\n help: \"获得访问权限的用户 / 组 / 角色 ID\"\n },\n access_level: {\n label: \"访问级别\",\n help: \"接收方可以执行的操作——read | edit | full(转移 / 共享 / 删除)\",\n options: {\n read: \"读取\",\n edit: \"编辑\",\n full: \"完全访问\"\n }\n },\n source: {\n label: \"来源\",\n help: \"该授权存在的原因——供规则求值器对账使用\",\n options: {\n manual: \"手动\",\n rule: \"规则\",\n team: \"团队\",\n inherited: \"继承\"\n }\n },\n source_id: {\n label: \"来源 ID\",\n help: \"当 source != manual 时,对应规则名 / 团队 ID\"\n },\n granted_by: {\n label: \"授权人\",\n help: \"创建该授权的用户(仅手动授权)\"\n },\n reason: {\n label: \"原因\",\n help: \"可选的自由文本说明,会展示给接收方\"\n },\n created_at: {\n label: \"创建时间\"\n },\n updated_at: {\n label: \"更新时间\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"授予我的\"\n },\n granted_by_me: {\n label: \"我授予的\"\n },\n by_object: {\n label: \"按对象\"\n },\n manual_grants: {\n label: \"手动授权\"\n },\n rule_grants: {\n label: \"规则授权\"\n },\n all_shares: {\n label: \"全部\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"共享规则\",\n pluralLabel: \"共享规则\",\n description: \"声明式共享规则,会自动生成 sys_record_share 授权。可在代码中通过 defineSharingRule() 编写,或在 Studio 条件构建器中维护。\",\n fields: {\n id: {\n label: \"规则 ID\"\n },\n organization_id: {\n label: \"组织\",\n help: \"拥有该规则的租户;null = 全局\"\n },\n name: {\n label: \"名称\",\n help: \"唯一的 snake_case 规则名称\"\n },\n label: {\n label: \"显示标签\"\n },\n description: {\n label: \"描述\"\n },\n object_name: {\n label: \"对象\",\n help: \"短对象名(例如 opportunity、account)\"\n },\n criteria_json: {\n label: \"条件(FilterCondition JSON)\",\n help: \"针对 object_name 记录匹配的 JSON FilterCondition。为空表示匹配全部。\"\n },\n recipient_type: {\n label: \"接收方类型\",\n help: \"接收访问权限的主体类型——求值时会展开为用户授权。`department` 会沿 parent_department_id 树展开;`team` 为扁平结构(better-auth)。\",\n options: {\n user: \"用户\",\n team: \"团队\",\n department: \"部门\",\n role: \"角色\",\n queue: \"队列\"\n }\n },\n recipient_id: {\n label: \"接收方\",\n help: \"根据 recipient_type 填写 department id / team id / role name / queue name / user id\"\n },\n access_level: {\n label: \"访问级别\",\n options: {\n read: \"读取\",\n edit: \"编辑\",\n full: \"完全访问\"\n }\n },\n active: {\n label: \"启用\",\n help: \"只有启用的规则才会参与生命周期求值\"\n },\n created_at: {\n label: \"创建时间\"\n },\n updated_at: {\n label: \"更新时间\"\n }\n },\n _views: {\n active: {\n label: \"启用\"\n },\n inactive: {\n label: \"停用\"\n },\n by_object: {\n label: \"按对象\"\n },\n all_rules: {\n label: \"全部\"\n }\n }\n },\n sys_share_link: {\n label: \"共享链接\",\n pluralLabel: \"共享链接\",\n description: \"授予对单条记录访问权限的不透明能力令牌。类似 Notion/Figma 的公开链接共享。\",\n fields: {\n id: {\n label: \"链接 ID\"\n },\n token: {\n label: \"令牌\",\n help: \"URL 安全的不透明随机令牌(≥ 22 个字符)。本记录中唯一的机密信息。\"\n },\n object_name: {\n label: \"对象\",\n help: \"所共享记录的对象短名称(例如 ai_conversation、contracts_contract)\"\n },\n record_id: {\n label: \"记录\",\n help: \"object_name 内所共享记录的主键\"\n },\n permission: {\n label: \"权限\",\n help: \"链接持有者可对该记录执行的操作\",\n options: {\n view: \"查看\",\n comment: \"评论\",\n edit: \"编辑\"\n }\n },\n audience: {\n label: \"受众\",\n help: \"在令牌校验之上额外施加的访问限制层\",\n options: {\n public: \"公开(可被索引)\",\n link_only: \"任何持有链接的人\",\n signed_in: \"已登录用户\",\n email: \"指定邮箱\"\n }\n },\n expires_at: {\n label: \"过期时间\",\n help: \"设置后,超过此时间点 resolveToken 将返回 null\"\n },\n email_allowlist: {\n label: \"邮箱白名单\",\n help: \"当 audience=email 时校验的小写邮箱地址\"\n },\n password_hash: {\n label: \"密码哈希\",\n help: \"Argon2/bcrypt 哈希值。设置后,界面会在呈现内容前提示输入密码。\"\n },\n redact_fields: {\n label: \"按链接脱敏字段\",\n help: \"在对象默认脱敏集之上,从响应中额外剔除的字段\"\n },\n label: {\n label: \"标签\",\n help: \"在共享对话框中显示的自由文本(例如 \\\"ACME Q3 合同\\\")\"\n },\n revoked_at: {\n label: \"撤销时间\",\n help: \"设置后,该链接将被永久停用\"\n },\n created_by: {\n label: \"创建人\",\n help: \"链接的签发者\"\n },\n created_at: {\n label: \"创建时间\"\n },\n last_used_at: {\n label: \"最近使用时间\",\n help: \"由 resolveToken 标记;仪表盘据此高亮显示活跃链接\"\n },\n use_count: {\n label: \"使用次数\",\n help: \"每次成功解析时由 resolveToken 递增\"\n }\n },\n _views: {\n active_links: {\n label: \"活跃\"\n },\n by_me: {\n label: \"我创建的\"\n },\n revoked: {\n label: \"已撤销\"\n },\n all_links: {\n label: \"全部\"\n }\n }\n }\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'ja-JP'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const jaJPObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"レコード共有\",\n pluralLabel: \"レコード共有\",\n description: \"レコードごとの共有付与 — OWD に明示的なアクセスを追加\",\n fields: {\n id: {\n label: \"共有 ID\"\n },\n object_name: {\n label: \"オブジェクト\",\n help: \"共有レコードの短いオブジェクト名\"\n },\n record_id: {\n label: \"レコード\",\n help: \"object_name 内の共有レコードの主キー\"\n },\n recipient_type: {\n label: \"受信者タイプ\",\n help: \"付与を保持するプリンシパルの種別\",\n options: {\n user: \"ユーザー\",\n group: \"グループ\",\n role: \"ロール\",\n role_and_subordinates: \"ロールと下位階層\",\n guest: \"ゲスト\"\n }\n },\n recipient_id: {\n label: \"受信者\",\n help: \"アクセスを受け取るユーザー/グループ/ロールの ID\"\n },\n access_level: {\n label: \"アクセスレベル\",\n help: \"受信者に許可される操作 — read | edit | full(転送/共有/削除)\",\n options: {\n read: \"閲覧\",\n edit: \"編集\",\n full: \"フルアクセス\"\n }\n },\n source: {\n label: \"ソース\",\n help: \"この付与が存在する理由 — ルール評価者が調整に使用\",\n options: {\n manual: \"手動\",\n rule: \"ルール\",\n team: \"チーム\",\n inherited: \"継承\"\n }\n },\n source_id: {\n label: \"ソース ID\",\n help: \"source != manual の場合のルール名 / チーム ID\"\n },\n granted_by: {\n label: \"付与者\",\n help: \"付与を作成したユーザー(手動のみ)\"\n },\n reason: {\n label: \"理由\",\n help: \"受信者に表示されるオプションの自由記述説明\"\n },\n created_at: {\n label: \"作成日時\"\n },\n updated_at: {\n label: \"更新日時\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"自分への付与\"\n },\n granted_by_me: {\n label: \"自分による付与\"\n },\n by_object: {\n label: \"オブジェクト別\"\n },\n manual_grants: {\n label: \"手動付与\"\n },\n rule_grants: {\n label: \"ルール付与\"\n },\n all_shares: {\n label: \"すべて\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"共有ルール\",\n pluralLabel: \"共有ルール\",\n description: \"sys_record_share 付与を自動マテリアライズする宣言的共有ルール。コードの defineSharingRule() または Studio の条件ビルダーで作成します。\",\n fields: {\n id: {\n label: \"ルール ID\"\n },\n organization_id: {\n label: \"組織\",\n help: \"このルールを所有するテナント。null = グローバル\"\n },\n name: {\n label: \"名前\",\n help: \"一意の snake_case ルール名\"\n },\n label: {\n label: \"表示名\"\n },\n description: {\n label: \"説明\"\n },\n object_name: {\n label: \"オブジェクト\",\n help: \"短いオブジェクト名(例: opportunity、account)\"\n },\n criteria_json: {\n label: \"条件(FilterCondition JSON)\",\n help: \"object_name のレコードに対してマッチする JSON FilterCondition。空 = すべてにマッチ。\"\n },\n recipient_type: {\n label: \"受信者タイプ\",\n help: \"アクセスを受け取るプリンシパルの種別 — 評価時にユーザー付与に展開されます。`department` は parent_department_id ツリーをたどります。`team` はフラット(better-auth)。\",\n options: {\n user: \"ユーザー\",\n team: \"チーム\",\n department: \"部門\",\n role: \"ロール\",\n queue: \"キュー\"\n }\n },\n recipient_id: {\n label: \"受信者\",\n help: \"recipient_type に応じた部門 ID / チーム ID / ロール名 / キュー名 / ユーザー ID\"\n },\n access_level: {\n label: \"アクセスレベル\",\n options: {\n read: \"閲覧\",\n edit: \"編集\",\n full: \"フルアクセス\"\n }\n },\n active: {\n label: \"有効\",\n help: \"有効なルールのみがライフサイクル評価に参加します\"\n },\n created_at: {\n label: \"作成日時\"\n },\n updated_at: {\n label: \"更新日時\"\n }\n },\n _views: {\n active: {\n label: \"有効\"\n },\n inactive: {\n label: \"無効\"\n },\n by_object: {\n label: \"オブジェクト別\"\n },\n all_rules: {\n label: \"すべて\"\n }\n }\n },\n sys_share_link: {\n label: \"共有リンク\",\n pluralLabel: \"共有リンク\",\n description: \"単一レコードへのアクセスを許可する不透明なケーパビリティトークン。Notion / Figma スタイルの公開リンク共有。\",\n fields: {\n id: {\n label: \"リンク ID\"\n },\n token: {\n label: \"トークン\",\n help: \"URL セーフな不透明ランダムトークン(22 文字以上)。この行で唯一の機密情報です。\"\n },\n object_name: {\n label: \"オブジェクト\",\n help: \"共有対象レコードのオブジェクト短縮名(例: ai_conversation、contracts_contract)\"\n },\n record_id: {\n label: \"レコード\",\n help: \"object_name 内における共有対象レコードの主キー\"\n },\n permission: {\n label: \"権限\",\n help: \"リンク保持者がレコードに対して実行できる操作\",\n options: {\n view: \"閲覧\",\n comment: \"コメント\",\n edit: \"編集\"\n }\n },\n audience: {\n label: \"対象者\",\n help: \"トークン検証の上に適用されるアクセス制御レイヤー\",\n options: {\n public: \"公開(インデックス可能)\",\n link_only: \"リンクを知っている全員\",\n signed_in: \"サインイン済みユーザー\",\n email: \"特定のメールアドレス\"\n }\n },\n expires_at: {\n label: \"有効期限\",\n help: \"設定すると、このタイムスタンプ以降は resolveToken が null を返します\"\n },\n email_allowlist: {\n label: \"メール許可リスト\",\n help: \"audience=email のときに照合される小文字のメールアドレス\"\n },\n password_hash: {\n label: \"パスワードハッシュ\",\n help: \"Argon2/bcrypt ハッシュ。設定すると、表示前に UI がパスワードの入力を求めます。\"\n },\n redact_fields: {\n label: \"リンク単位のマスキング\",\n help: \"オブジェクト既定のマスキング集合に加えて、レスポンスから除外する追加フィールド\"\n },\n label: {\n label: \"ラベル\",\n help: \"共有ダイアログに表示される自由記述テキスト(例: \\\"ACME Q3 contract\\\")\"\n },\n revoked_at: {\n label: \"失効日時\",\n help: \"設定すると、リンクは恒久的に無効化されます\"\n },\n created_by: {\n label: \"作成者\",\n help: \"リンクの発行者\"\n },\n created_at: {\n label: \"作成日時\"\n },\n last_used_at: {\n label: \"最終使用日時\",\n help: \"resolveToken によって記録されます。ダッシュボードでアクティブなリンクを強調表示するために使用されます\"\n },\n use_count: {\n label: \"使用回数\",\n help: \"解決が成功するたびに resolveToken によって加算されます\"\n }\n },\n _views: {\n active_links: {\n label: \"アクティブ\"\n },\n by_me: {\n label: \"自分が作成\"\n },\n revoked: {\n label: \"失効済み\"\n },\n all_links: {\n label: \"すべて\"\n }\n }\n }\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'es-ES'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const esESObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"Compartición de registro\",\n pluralLabel: \"Comparticiones de registro\",\n description: \"Concesión de compartición por registro; amplía OWD con acceso explícito.\",\n fields: {\n id: {\n label: \"ID de compartición\"\n },\n object_name: {\n label: \"Objeto\",\n help: \"Nombre corto del objeto del registro compartido.\"\n },\n record_id: {\n label: \"Registro\",\n help: \"Clave primaria del registro compartido dentro de object_name.\"\n },\n recipient_type: {\n label: \"Tipo de destinatario\",\n help: \"Tipo de principal que posee la concesión.\",\n options: {\n user: \"Usuario\",\n group: \"Grupo\",\n role: \"Rol\",\n role_and_subordinates: \"Rol y subordinados\",\n guest: \"Invitado\"\n }\n },\n recipient_id: {\n label: \"Destinatario\",\n help: \"ID del usuario/grupo/rol que recibe acceso.\"\n },\n access_level: {\n label: \"Nivel de acceso\",\n help: \"Lo que puede hacer el destinatario: read | edit | full (transfer/share/delete).\",\n options: {\n read: \"Leer\",\n edit: \"Editar\",\n full: \"Total\"\n }\n },\n source: {\n label: \"Origen\",\n help: \"Motivo por el que existe esta concesión; lo utiliza el evaluador de reglas para reconciliar.\",\n options: {\n manual: \"Manual\",\n rule: \"Regla\",\n team: \"Equipo\",\n inherited: \"Heredado\"\n }\n },\n source_id: {\n label: \"ID de origen\",\n help: \"Nombre de la regla / ID del equipo cuando source != manual.\"\n },\n granted_by: {\n label: \"Concedido por\",\n help: \"Usuario que creó la concesión (solo manual).\"\n },\n reason: {\n label: \"Motivo\",\n help: \"Explicación opcional en texto libre que se muestra al destinatario.\"\n },\n created_at: {\n label: \"Creado el\"\n },\n updated_at: {\n label: \"Actualizado el\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"Concedidos a mí\"\n },\n granted_by_me: {\n label: \"Concedidos por mí\"\n },\n by_object: {\n label: \"Por objeto\"\n },\n manual_grants: {\n label: \"Concesiones manuales\"\n },\n rule_grants: {\n label: \"Concesiones por regla\"\n },\n all_shares: {\n label: \"Todas\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"Regla de compartición\",\n pluralLabel: \"Reglas de compartición\",\n description: \"Regla de compartición declarativa que materializa automáticamente concesiones de sys_record_share. Se define mediante defineSharingRule() en código o con el generador de criterios de Studio.\",\n fields: {\n id: {\n label: \"ID de regla\"\n },\n organization_id: {\n label: \"Organización\",\n help: \"Tenant que posee esta regla; null = global.\"\n },\n name: {\n label: \"Nombre\",\n help: \"Nombre de regla snake_case único.\"\n },\n label: {\n label: \"Nombre visible\"\n },\n description: {\n label: \"Descripción\"\n },\n object_name: {\n label: \"Objeto\",\n help: \"Nombre corto del objeto (p. ej. opportunity, account).\"\n },\n criteria_json: {\n label: \"Criterios (JSON de FilterCondition)\",\n help: \"FilterCondition JSON comparado con los registros de object_name. Vacío = coincide con todos.\"\n },\n recipient_type: {\n label: \"Tipo de destinatario\",\n help: \"Tipo de principal que recibe acceso; se expande a concesiones de usuario durante la evaluación. `department` recorre el árbol parent_department_id; `team` es plano (better-auth).\",\n options: {\n user: \"Usuario\",\n team: \"Equipo\",\n department: \"Departamento\",\n role: \"Rol\",\n queue: \"Cola\"\n }\n },\n recipient_id: {\n label: \"Destinatario\",\n help: \"ID de departamento / ID de equipo / nombre del rol / nombre de la cola / ID del usuario según recipient_type.\"\n },\n access_level: {\n label: \"Nivel de acceso\",\n options: {\n read: \"Leer\",\n edit: \"Editar\",\n full: \"Total\"\n }\n },\n active: {\n label: \"Activo\",\n help: \"Solo las reglas activas participan en la evaluación del ciclo de vida.\"\n },\n created_at: {\n label: \"Creado el\"\n },\n updated_at: {\n label: \"Actualizado el\"\n }\n },\n _views: {\n active: {\n label: \"Activo\"\n },\n inactive: {\n label: \"Inactivo\"\n },\n by_object: {\n label: \"Por objeto\"\n },\n all_rules: {\n label: \"Todas\"\n }\n }\n },\n sys_share_link: {\n label: \"Enlace de uso compartido\",\n pluralLabel: \"Enlaces de uso compartido\",\n description: \"Token de capacidad opaco que concede acceso a un único registro. Uso compartido mediante enlace público al estilo de Notion/Figma.\",\n fields: {\n id: {\n label: \"ID del enlace\"\n },\n token: {\n label: \"Token\",\n help: \"Token aleatorio opaco seguro para URL (≥ 22 caracteres). El único secreto de esta fila.\"\n },\n object_name: {\n label: \"Objeto\",\n help: \"Nombre corto del objeto del registro compartido (p. ej. ai_conversation, contracts_contract)\"\n },\n record_id: {\n label: \"Registro\",\n help: \"Clave principal del registro compartido dentro de object_name\"\n },\n permission: {\n label: \"Permiso\",\n help: \"Lo que el titular del enlace puede hacer con el registro\",\n options: {\n view: \"Ver\",\n comment: \"Comentar\",\n edit: \"Editar\"\n }\n },\n audience: {\n label: \"Audiencia\",\n help: \"Capa de control aplicada por encima de la verificación del token\",\n options: {\n public: \"Público (indexable)\",\n link_only: \"Cualquier persona con el enlace\",\n signed_in: \"Usuarios con sesión iniciada\",\n email: \"Correos específicos\"\n }\n },\n expires_at: {\n label: \"Caduca el\",\n help: \"Cuando se establece, resolveToken devuelve null después de esta marca de tiempo\"\n },\n email_allowlist: {\n label: \"Lista de correos permitidos\",\n help: \"Direcciones en minúsculas que se comprueban cuando audience=email\"\n },\n password_hash: {\n label: \"Hash de contraseña\",\n help: \"Hash Argon2/bcrypt. Cuando se establece, la interfaz solicita una contraseña antes de mostrar el contenido.\"\n },\n redact_fields: {\n label: \"Campos ocultos por enlace\",\n help: \"Campos adicionales que se eliminan de la respuesta, además del conjunto predeterminado del objeto\"\n },\n label: {\n label: \"Etiqueta\",\n help: \"Texto libre que se muestra en el cuadro de diálogo de uso compartido (p. ej. \\\"ACME Q3 contract\\\")\"\n },\n revoked_at: {\n label: \"Revocado el\",\n help: \"Cuando se establece, el enlace queda deshabilitado permanentemente\"\n },\n created_by: {\n label: \"Creado por\",\n help: \"Emisor del enlace\"\n },\n created_at: {\n label: \"Creado el\"\n },\n last_used_at: {\n label: \"Último uso el\",\n help: \"Lo registra resolveToken; el panel lo usa para resaltar los enlaces activos\"\n },\n use_count: {\n label: \"Número de usos\",\n help: \"Lo incrementa resolveToken en cada resolución correcta\"\n }\n },\n _views: {\n active_links: {\n label: \"Activos\"\n },\n by_me: {\n label: \"Creados por mí\"\n },\n revoked: {\n label: \"Revocados\"\n },\n all_links: {\n label: \"Todos\"\n }\n }\n }\n};\n","// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * SharingTranslations — i18n bundle owned by this plugin (ADR-0029 D8).\n *\n * Object label/field/view/action translations for the sys_* objects this\n * plugin owns. Loaded at runtime via the plugin's `kernel:ready` hook\n * (`i18n.loadTranslations`). Regenerate with `os i18n extract` against\n * `scripts/i18n-extract.config.ts`.\n */\n\nimport type { TranslationBundle } from '@objectstack/spec/system';\nimport { enObjects } from './en.objects.generated.js';\nimport { zhCNObjects } from './zh-CN.objects.generated.js';\nimport { jaJPObjects } from './ja-JP.objects.generated.js';\nimport { esESObjects } from './es-ES.objects.generated.js';\n\nexport const SharingTranslations: TranslationBundle = {\n en: { objects: enObjects },\n 'zh-CN': { objects: zhCNObjects },\n 'ja-JP': { objects: jaJPObjects },\n 'es-ES': { objects: esESObjects },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * @objectstack/plugin-sharing\n *\n * Record-level sharing for ObjectStack. Implements `ISharingService`\n * and installs an engine middleware that enforces\n * `object.sharingModel` (`private` / `read`) against the\n * authenticated execution context.\n */\n\nexport { SysRecordShare, SysSharingRule, SysShareLink } from './objects/index.js';\nexport { SysDepartment, SysDepartmentMember } from '@objectstack/platform-objects/identity';\nexport {\n SharingService,\n type SharingEngine,\n type SharingServiceOptions,\n} from './sharing-service.js';\nexport {\n SharingRuleService,\n type SharingRuleServiceOptions,\n} from './sharing-rule-service.js';\nexport {\n ShareLinkService,\n type ShareLinkServiceOptions,\n} from './share-link-service.js';\nexport {\n registerShareLinkRoutes,\n type ShareLinkRoutesOptions,\n} from './share-link-routes.js';\nexport { TeamGraphService, expandPrincipal, type TeamGraphOptions } from './team-graph.js';\nexport { DepartmentGraphService, type DepartmentGraphOptions } from './department-graph.js';\nexport { bindRuleHooks, unbindAllRuleHooks, SHARING_RULE_HOOK_PACKAGE } from './rule-hooks.js';\nexport {\n SharingServicePlugin,\n buildSharingMiddleware,\n type SharingPluginOptions,\n} from './sharing-plugin.js';\nexport type {\n ISharingService,\n ISharingRuleService,\n ITeamGraphService,\n IDepartmentGraphService,\n RecordShare,\n GrantShareInput,\n SharingExecutionContext,\n ShareAccessLevel,\n ShareRecipientType,\n ShareSource,\n SharingRuleRow,\n DefineSharingRuleInput,\n SharingRuleEvaluationResult,\n SharingRuleRecipientType,\n IShareLinkService,\n ShareLink,\n CreateShareLinkInput,\n ListShareLinksFilter,\n ResolveShareLinkResult,\n ShareLinkExecutionContext,\n ShareLinkPermission,\n ShareLinkAudience,\n} from '@objectstack/spec/contracts';\nexport { SHARE_LINK_SERVICE } from '@objectstack/spec/contracts';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_record_share — Per-Record Sharing Grant\n *\n * Bridges the ownership-only baseline established by `object.sharingModel`\n * with the real-world need to delegate access to a single record. Each\n * row says: \"principal P has access level L on (object O, record R),\n * because of source S (manual grant or rule).\"\n *\n * Enforcement lives in `@objectstack/plugin-sharing`:\n * - For objects with `sharingModel: 'private'`, the engine middleware\n * AND-s `{$or:[{owner_id:userId},{id:{$in:[grantedRecordIds]}}]}`\n * into every `find` against that object.\n * - For objects with `sharingModel: 'private' | 'read'`, the same\n * middleware enforces edit/delete by checking ownership OR a share\n * row with `access_level in ('edit','full')`.\n *\n * Conventions:\n * - `object_name` is the short object name (e.g. `account`, `lead`).\n * - `recipient_type` mirrors `ShareRecipientType` from the spec\n * (`user` is enforced today; `group`/`role` are persisted for\n * forward-compatibility).\n * - `source = 'manual'` rows are created by a user via the REST\n * `POST /data/:object/:id/shares` endpoint. `source = 'rule'` rows\n * are materialised by the sharing-rule evaluator (future); the\n * `source_id` lets the evaluator reconcile stale grants.\n *\n * @namespace sys\n */\nexport const SysRecordShare = ObjectSchema.create({\n name: 'sys_record_share',\n label: 'Record Share',\n pluralLabel: 'Record Shares',\n icon: 'share',\n isSystem: true,\n managedBy: 'system',\n description: 'Per-record sharing grant — extends OWD with explicit access',\n titleFormat: '{object_name}/{record_id} → {recipient_id} ({access_level})',\n compactLayout: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source'],\n\n listViews: {\n granted_to_me: {\n type: 'grid',\n name: 'granted_to_me',\n label: 'Granted to Me',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'access_level', 'source', 'granted_by', 'created_at'],\n filter: [\n { field: 'recipient_type', operator: 'equals', value: 'user' },\n { field: 'recipient_id', operator: 'equals', value: '{current_user_id}' },\n ],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n granted_by_me: {\n type: 'grid',\n name: 'granted_by_me',\n label: 'Granted by Me',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source', 'created_at'],\n filter: [\n { field: 'granted_by', operator: 'equals', value: '{current_user_id}' },\n ],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n by_object: {\n type: 'grid',\n name: 'by_object',\n label: 'By Object',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source', 'created_at'],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'created_at', order: 'desc' }],\n grouping: { fields: [{ field: 'object_name', order: 'asc', collapsed: false }] },\n pagination: { pageSize: 100 },\n },\n manual_grants: {\n type: 'grid',\n name: 'manual_grants',\n label: 'Manual Grants',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'granted_by', 'reason', 'created_at'],\n filter: [{ field: 'source', operator: 'equals', value: 'manual' }],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n rule_grants: {\n type: 'grid',\n name: 'rule_grants',\n label: 'Rule Grants',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source_id', 'created_at'],\n filter: [{ field: 'source', operator: 'in', value: ['rule', 'team', 'inherited'] }],\n sort: [{ field: 'source_id', order: 'asc' }, { field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n all_shares: {\n type: 'grid',\n name: 'all_shares',\n label: 'All',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_type', 'recipient_id', 'access_level', 'source', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 100 },\n },\n },\n\n fields: {\n id: Field.text({\n label: 'Share ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n // ── Target (which record is being shared) ────────────────────\n object_name: Field.text({\n label: 'Object',\n required: true,\n maxLength: 100,\n description: 'Short object name of the shared record',\n group: 'Target',\n }),\n\n record_id: Field.text({\n label: 'Record',\n required: true,\n maxLength: 100,\n description: 'Primary key of the shared record within object_name',\n group: 'Target',\n }),\n\n // ── Recipient (who receives access) ──────────────────────────\n recipient_type: Field.select(\n ['user', 'group', 'role', 'role_and_subordinates', 'guest'],\n {\n label: 'Recipient Type',\n required: true,\n defaultValue: 'user',\n description: 'Kind of principal that holds the grant',\n group: 'Recipient',\n },\n ),\n\n recipient_id: Field.text({\n label: 'Recipient',\n required: true,\n maxLength: 100,\n description: 'ID of the user/group/role that receives access',\n group: 'Recipient',\n }),\n\n access_level: Field.select(\n ['read', 'edit', 'full'],\n {\n label: 'Access Level',\n required: true,\n defaultValue: 'read',\n description: 'What the recipient can do — read | edit | full (transfer/share/delete)',\n group: 'Recipient',\n },\n ),\n\n // ── Provenance ───────────────────────────────────────────────\n source: Field.select(\n ['manual', 'rule', 'team', 'inherited'],\n {\n label: 'Source',\n required: true,\n defaultValue: 'manual',\n description: 'Why this grant exists — used by the rule evaluator to reconcile',\n group: 'Provenance',\n },\n ),\n\n source_id: Field.text({\n label: 'Source ID',\n required: false,\n maxLength: 200,\n description: 'Rule name / team id when source != manual',\n group: 'Provenance',\n }),\n\n granted_by: Field.lookup('sys_user', {\n label: 'Granted By',\n required: false,\n description: 'User that created the grant (manual only)',\n group: 'Provenance',\n }),\n\n reason: Field.text({\n label: 'Reason',\n required: false,\n maxLength: 500,\n description: 'Optional free-text explanation surfaced to the recipient',\n group: 'Provenance',\n }),\n\n // ── Lifecycle ────────────────────────────────────────────────\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n required: false,\n group: 'System',\n }),\n },\n\n indexes: [\n // Hot path: \"all records visible to user U on object O\" — the\n // middleware reads (object_name, recipient_type, recipient_id) to\n // build the `id IN (...)` predicate on every find.\n { fields: ['object_name', 'recipient_type', 'recipient_id'] },\n // \"all grants on this record\" — used by the share-management UI\n // and by canEdit() to look up explicit grants.\n { fields: ['object_name', 'record_id'] },\n // Reconciliation key for rule-driven shares.\n { fields: ['source', 'source_id'] },\n ],\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_sharing_rule — Declarative record-sharing rule.\n *\n * Salesforce-style criteria-based sharing: \"any record on object O that\n * matches criteria C is granted access level A to recipient R\". Rules\n * are evaluated by `@objectstack/plugin-sharing` and materialise their\n * grants as rows in `sys_record_share` with `source='rule'` and\n * `source_id={rule.id}` so the evaluator can reconcile (delete + re-\n * insert) on rule updates without touching manual grants.\n *\n * Evaluation triggers:\n * - `afterInsert` / `afterUpdate` on the target object (per-record,\n * incremental — the hot path).\n * - REST `POST /sharing/rules/:id/evaluate` (admin-initiated\n * bulk reconcile — used after rule edits).\n *\n * Criteria are stored as JSON (a normal `FilterCondition`) so the\n * existing engine `find()` can do the matching natively. v1 supports\n * simple `{field, op, value}` style filters; CEL predicates are a\n * follow-up.\n *\n * @namespace sys\n */\nexport const SysSharingRule = ObjectSchema.create({\n name: 'sys_sharing_rule',\n label: 'Sharing Rule',\n pluralLabel: 'Sharing Rules',\n icon: 'shield-check',\n isSystem: true,\n managedBy: 'config',\n // Sharing rules can now be authored visually via the Studio criteria\n // builder (apps/studio/src/components/SharingCriteriaBuilder.tsx).\n // We still recommend `defineSharingRule({...})` for repo-controlled\n // baselines, but admins can safely create/edit/delete from the UI.\n userActions: { create: true, edit: true, delete: true, import: false },\n description: 'Declarative sharing rule that auto-materialises sys_record_share grants. Authored via defineSharingRule() in code or the Studio criteria builder.',\n displayNameField: 'name',\n titleFormat: '{label}',\n compactLayout: ['name', 'object_name', 'recipient_type', 'recipient_id', 'access_level', 'active'],\n\n listViews: {\n active: {\n type: 'grid',\n name: 'active',\n label: 'Active',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['label', 'object_name', 'recipient_type', 'recipient_id', 'access_level', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: true }],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n inactive: {\n type: 'grid',\n name: 'inactive',\n label: 'Inactive',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['label', 'object_name', 'recipient_type', 'recipient_id', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: false }],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n by_object: {\n type: 'grid',\n name: 'by_object',\n label: 'By Object',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['object_name', 'label', 'recipient_type', 'access_level', 'active'],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'label', order: 'asc' }],\n grouping: { fields: [{ field: 'object_name', order: 'asc', collapsed: false }] },\n pagination: { pageSize: 100 },\n },\n all_rules: {\n type: 'grid',\n name: 'all_rules',\n label: 'All',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['label', 'object_name', 'recipient_type', 'recipient_id', 'access_level', 'active', 'updated_at'],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n },\n\n fields: {\n id: Field.text({ label: 'Rule ID', required: true, readonly: true, group: 'System' }),\n\n organization_id: Field.lookup('sys_organization', {\n label: 'Organization',\n required: false,\n group: 'System',\n description: 'Tenant that owns this rule; null = global',\n }),\n\n name: Field.text({\n label: 'Name',\n required: true,\n maxLength: 100,\n description: 'Unique snake_case rule name',\n group: 'Identity',\n }),\n\n label: Field.text({\n label: 'Display Label',\n required: true,\n maxLength: 200,\n group: 'Identity',\n }),\n\n description: Field.textarea({\n label: 'Description',\n required: false,\n group: 'Identity',\n }),\n\n object_name: Field.text({\n label: 'Object',\n required: true,\n maxLength: 100,\n description: 'Short object name (e.g. opportunity, account)',\n group: 'Target',\n }),\n\n criteria_json: Field.textarea({\n label: 'Criteria (FilterCondition JSON)',\n required: false,\n description: 'JSON FilterCondition matched against records of object_name. Empty = match all.',\n group: 'Target',\n }),\n\n recipient_type: Field.select(\n ['user', 'team', 'department', 'role', 'queue'],\n {\n label: 'Recipient Type',\n required: true,\n defaultValue: 'department',\n description: 'Kind of principal that receives access — expanded to user grants at evaluation time. `department` walks the parent_department_id tree; `team` is flat (better-auth).',\n group: 'Recipient',\n },\n ),\n\n recipient_id: Field.text({\n label: 'Recipient',\n required: true,\n maxLength: 200,\n description: 'department id / team id / role name / queue name / user id depending on recipient_type',\n group: 'Recipient',\n }),\n\n access_level: Field.select(\n ['read', 'edit', 'full'],\n {\n label: 'Access Level',\n required: true,\n defaultValue: 'read',\n group: 'Recipient',\n },\n ),\n\n active: Field.boolean({\n label: 'Active',\n required: false,\n defaultValue: true,\n description: 'Only active rules participate in lifecycle evaluation',\n group: 'Lifecycle',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n required: false,\n group: 'System',\n }),\n },\n\n indexes: [\n { fields: ['object_name', 'active'] },\n { fields: ['name'], unique: true },\n { fields: ['organization_id'] },\n ],\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_share_link — Capability-Token Public Share Links\n *\n * Each row authorises read (or write) access to ONE record of ONE\n * object via an opaque URL-safe token. Complements `sys_record_share`,\n * which models principal-based grants (share with a specific user /\n * team / role). A single record may have rows in both tables; the\n * union determines effective access.\n *\n * Lifecycle:\n *\n * 1. `IShareLinkService.createLink` validates the request against the\n * target object's `publicSharing` whitelist and inserts a row.\n * Token is a 24-char URL-safe random string.\n *\n * 2. `IShareLinkService.resolveToken` (called from the public\n * `/api/v1/share-links/:token` middleware on every request)\n * verifies the row is not revoked / not expired, applies audience\n * / password gates, increments `use_count` + `last_used_at`, and\n * returns the effective redaction set.\n *\n * 3. `IShareLinkService.revokeLink` stamps `revoked_at`. Rows are\n * preserved for audit; resolveToken returns null after revocation.\n *\n * Conventions:\n * - `object_name` is the short object name (`account`, `ai_conversation`, …)\n * - `record_id` is the primary key of the target record within object_name\n * - `audience` mirrors `ShareLinkAudience` in spec/contracts; the\n * middleware enforces additional gating per audience\n * - `redact_fields` overlays on top of the schema-default redaction\n * set declared on `object.publicSharing.redactFields`\n *\n * managedBy: 'system' — admins inspect via the audit grid but all\n * writes flow through `IShareLinkService` so the per-object opt-in,\n * expiry caps, and audit hooks fire.\n *\n * @namespace sys\n */\nexport const SysShareLink = ObjectSchema.create({\n name: 'sys_share_link',\n label: 'Share Link',\n pluralLabel: 'Share Links',\n icon: 'link-2',\n isSystem: true,\n managedBy: 'system',\n description: 'Opaque capability token granting access to a single record. Notion/Figma-style public link sharing.',\n titleFormat: '{object_name}/{record_id} ({permission})',\n compactLayout: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'revoked_at'],\n\n listViews: {\n active_links: {\n type: 'grid',\n name: 'active_links',\n label: 'Active',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'use_count', 'last_used_at'],\n filter: [{ field: 'revoked_at', operator: 'isNull' }],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 100 },\n },\n by_me: {\n type: 'grid',\n name: 'by_me',\n label: 'Created by Me',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'revoked_at'],\n filter: [{ field: 'created_by', operator: 'equals', value: '{current_user_id}' }],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 100 },\n },\n revoked: {\n type: 'grid',\n name: 'revoked',\n label: 'Revoked',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'revoked_at', 'created_by'],\n filter: [{ field: 'revoked_at', operator: 'isNotNull' }],\n sort: [{ field: 'revoked_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n all_links: {\n type: 'grid',\n name: 'all_links',\n label: 'All',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'revoked_at', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 200 },\n },\n },\n\n fields: {\n id: Field.text({\n label: 'Link ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n // ── Token (the secret) ───────────────────────────────────────\n token: Field.text({\n label: 'Token',\n required: true,\n maxLength: 64,\n description: 'Opaque URL-safe random token (≥ 22 chars). The only secret in this row.',\n group: 'Token',\n }),\n\n // ── Target ───────────────────────────────────────────────────\n object_name: Field.text({\n label: 'Object',\n required: true,\n maxLength: 100,\n description: 'Short object name of the shared record (e.g. ai_conversation, contracts_contract)',\n group: 'Target',\n }),\n\n record_id: Field.text({\n label: 'Record',\n required: true,\n maxLength: 100,\n description: 'Primary key of the shared record within object_name',\n group: 'Target',\n }),\n\n // ── Access Policy ────────────────────────────────────────────\n permission: Field.select(\n [\n { label: 'View', value: 'view' },\n { label: 'Comment', value: 'comment' },\n { label: 'Edit', value: 'edit' },\n ],\n {\n label: 'Permission',\n required: true,\n defaultValue: 'view',\n description: 'What the link holder can do with the record',\n group: 'Access Policy',\n },\n ),\n\n audience: Field.select(\n [\n { label: 'Public (indexable)', value: 'public' },\n { label: 'Anyone with the link', value: 'link_only' },\n { label: 'Signed-in users', value: 'signed_in' },\n { label: 'Specific emails', value: 'email' },\n ],\n {\n label: 'Audience',\n required: true,\n defaultValue: 'link_only',\n description: 'Gating layer applied on top of the token check',\n group: 'Access Policy',\n },\n ),\n\n expires_at: Field.datetime({\n label: 'Expires At',\n description: 'When set, resolveToken returns null after this timestamp',\n group: 'Access Policy',\n }),\n\n email_allowlist: Field.json({\n label: 'Email Allowlist',\n description: 'Lowercased addresses checked when audience=email',\n group: 'Access Policy',\n }),\n\n password_hash: Field.text({\n label: 'Password Hash',\n maxLength: 256,\n description: 'Argon2/bcrypt hash. When set, the UI prompts for a password before rendering.',\n group: 'Access Policy',\n }),\n\n redact_fields: Field.json({\n label: 'Per-Link Redactions',\n description: 'Extra fields stripped from the response, on top of the object-default set',\n group: 'Access Policy',\n }),\n\n label: Field.text({\n label: 'Label',\n maxLength: 200,\n description: 'Free-text shown in the share dialog (e.g. \"ACME Q3 contract\")',\n group: 'Metadata',\n }),\n\n // ── Lifecycle ────────────────────────────────────────────────\n revoked_at: Field.datetime({\n label: 'Revoked At',\n readonly: true,\n description: 'When set, the link is permanently disabled',\n group: 'Lifecycle',\n }),\n\n created_by: Field.lookup('sys_user', {\n label: 'Created By',\n readonly: true,\n description: 'Issuer of the link',\n group: 'Lifecycle',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'Lifecycle',\n }),\n\n last_used_at: Field.datetime({\n label: 'Last Used At',\n readonly: true,\n description: 'Stamped by resolveToken; used by the dashboard to highlight active links',\n group: 'Lifecycle',\n }),\n\n use_count: Field.number({\n label: 'Use Count',\n defaultValue: 0,\n readonly: true,\n description: 'Incremented by resolveToken on every successful resolution',\n group: 'Lifecycle',\n }),\n },\n\n indexes: [\n // Hot path: resolveToken — one row lookup per public request.\n { fields: ['token'], unique: true },\n // Management UI: \"all links for this record\".\n { fields: ['object_name', 'record_id'] },\n // \"Active links I issued\".\n { fields: ['created_by', 'revoked_at'] },\n // Reaper for expired rows (background sweep).\n { fields: ['expires_at'] },\n ],\n\n enable: {\n trackHistory: false,\n searchable: false,\n apiEnabled: true,\n // The /api/v1/share-links endpoints are the authoritative surface;\n // the generic data API is exposed read-only for the admin grid.\n apiMethods: ['get', 'list'],\n trash: false,\n mru: false,\n clone: false,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n ISharingService,\n RecordShare,\n GrantShareInput,\n SharingExecutionContext,\n ShareAccessLevel,\n} from '@objectstack/spec/contracts';\n\n/**\n * Shape of the data engine the service actually needs. Kept narrow so\n * unit tests can pass an in-memory fake without depending on the full\n * ObjectQL engine class.\n */\nexport interface SharingEngine {\n find(object: string, options?: any): Promise<any[]>;\n findOne?(object: string, options?: any): Promise<any>;\n insert(object: string, data: any, options?: any): Promise<any>;\n update(object: string, idOrData: any, dataOrOptions?: any, options?: any): Promise<any>;\n delete(object: string, options?: any): Promise<any>;\n getSchema?(object: string): any | undefined;\n}\n\n/**\n * Random share id. Keeps the plugin self-contained (no `crypto.randomUUID`\n * dependency in environments that don't expose it on `globalThis`).\n */\nfunction makeShareId(): string {\n const g: any = globalThis as any;\n if (g.crypto?.randomUUID) return `shr_${g.crypto.randomUUID()}`;\n return `shr_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** System-elevated context for the plugin's own queries / mutations. */\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\n/**\n * Owner field convention. Hard-coded to `owner_id` for MVP — the\n * sharing model in Salesforce / ServiceNow / Dynamics all assume a\n * single owner field, and customising it is a follow-up. Objects\n * without `owner_id` are treated as \"unowned\" and read filters are\n * suppressed (they fall back to OWD-public behaviour).\n */\nconst OWNER_FIELD = 'owner_id';\n\n/**\n * Effective sharing model. Anything other than `private` / `read` is\n * treated as public — that includes objects that don't declare\n * `sharingModel` at all, so existing CRM behaviour is preserved\n * until an admin opts an object in.\n */\nfunction effectiveSharingModel(schema: any): 'private' | 'read' | 'public' {\n const m = schema?.sharingModel ?? schema?.security?.sharingModel;\n if (m === 'private') return 'private';\n if (m === 'read') return 'read';\n return 'public';\n}\n\nfunction hasOwnerField(schema: any): boolean {\n return Boolean(schema?.fields && OWNER_FIELD in schema.fields);\n}\n\nexport interface SharingServiceOptions {\n engine: SharingEngine;\n /** Object names that bypass sharing — typically platform internals. */\n bypassObjects?: string[];\n}\n\n/**\n * Default `ISharingService` implementation.\n *\n * Stores every grant in `sys_record_share`. The plugin layer registers\n * an engine middleware that calls `buildReadFilter` / `canEdit` so that\n * neither this class nor its callers need to know about middleware\n * plumbing.\n */\nexport class SharingService implements ISharingService {\n private readonly engine: SharingEngine;\n private readonly bypassObjects: Set<string>;\n\n constructor(options: SharingServiceOptions) {\n this.engine = options.engine;\n this.bypassObjects = new Set([\n 'sys_record_share',\n 'sys_user',\n 'sys_organization',\n 'sys_member',\n 'sys_role',\n 'sys_permission_set',\n 'sys_user_permission_set',\n 'sys_role_permission_set',\n ...(options.bypassObjects ?? []),\n ]);\n }\n\n /**\n * Build a `FilterCondition` restricting `find` to records the caller\n * may see. Returns `null` when no filter should be applied.\n */\n async buildReadFilter(\n object: string,\n context: SharingExecutionContext,\n ): Promise<unknown | null> {\n if (this.shouldBypass(object, context)) return null;\n\n const schema = this.engine.getSchema?.(object);\n if (!schema) return null;\n if (effectiveSharingModel(schema) !== 'private') return null;\n if (!hasOwnerField(schema)) return null;\n if (!context.userId) {\n // Authenticated context with no user id is a degenerate case\n // (e.g. anonymous API key). Restrict to nothing rather than\n // accidentally leaking owner-only data.\n return { id: '__deny_all__' };\n }\n\n const grants = await this.engine.find('sys_record_share', {\n filter: {\n object_name: object,\n recipient_type: 'user',\n recipient_id: context.userId,\n },\n fields: ['record_id', 'access_level'],\n limit: 5000,\n context: SYSTEM_CTX,\n });\n\n const grantedIds: string[] = Array.isArray(grants)\n ? grants.map((g: any) => String(g.record_id)).filter(Boolean)\n : [];\n\n if (grantedIds.length === 0) {\n return { [OWNER_FIELD]: context.userId };\n }\n\n return {\n $or: [\n { [OWNER_FIELD]: context.userId },\n { id: { $in: grantedIds } },\n ],\n };\n }\n\n /**\n * Return `true` if the caller may edit `(object, recordId)`. Always\n * `true` for system context, public objects, and objects without an\n * owner field.\n */\n async canEdit(\n object: string,\n recordId: string,\n context: SharingExecutionContext,\n ): Promise<boolean> {\n if (this.shouldBypass(object, context)) return true;\n\n const schema = this.engine.getSchema?.(object);\n if (!schema) return true;\n const model = effectiveSharingModel(schema);\n if (model === 'public') return true;\n if (!hasOwnerField(schema)) return true;\n if (!context.userId) return false;\n\n // 1) Ownership — fast path.\n const own = await this.engine.find(object, {\n filter: { id: recordId },\n fields: ['id', OWNER_FIELD],\n limit: 1,\n context: SYSTEM_CTX,\n });\n const owner = Array.isArray(own) && own[0] ? (own[0] as any)[OWNER_FIELD] : undefined;\n if (owner && String(owner) === String(context.userId)) return true;\n\n // 2) Explicit edit / full share.\n const editGrants = await this.engine.find('sys_record_share', {\n filter: {\n object_name: object,\n record_id: recordId,\n recipient_type: 'user',\n recipient_id: context.userId,\n access_level: { $in: ['edit', 'full'] },\n },\n fields: ['id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n return Array.isArray(editGrants) && editGrants.length > 0;\n }\n\n /**\n * Upsert a share row. Returning the existing row when an identical\n * grant already exists keeps the REST endpoint idempotent.\n */\n async grant(\n input: GrantShareInput,\n context: SharingExecutionContext,\n ): Promise<RecordShare> {\n if (!input.object) throw new Error('VALIDATION_FAILED: object is required');\n if (!input.recordId) throw new Error('VALIDATION_FAILED: recordId is required');\n if (!input.recipientId) throw new Error('VALIDATION_FAILED: recipientId is required');\n\n const recipientType = input.recipientType ?? 'user';\n const accessLevel: ShareAccessLevel = input.accessLevel ?? 'read';\n const source = input.source ?? 'manual';\n\n // Upsert: if a row with same (object, record, recipient) exists,\n // update its access level / reason; otherwise insert a new one.\n const existing = await this.engine.find('sys_record_share', {\n filter: {\n object_name: input.object,\n record_id: input.recordId,\n recipient_type: recipientType,\n recipient_id: input.recipientId,\n },\n limit: 1,\n context: SYSTEM_CTX,\n });\n const now = new Date().toISOString();\n if (Array.isArray(existing) && existing[0]) {\n const row: any = existing[0];\n const patch: any = {\n id: row.id,\n access_level: accessLevel,\n source,\n source_id: input.sourceId ?? row.source_id ?? null,\n reason: input.reason ?? row.reason ?? null,\n updated_at: now,\n };\n await this.engine.update('sys_record_share', patch, { context: SYSTEM_CTX });\n return { ...row, ...patch } as RecordShare;\n }\n\n const id = makeShareId();\n const row: any = {\n id,\n object_name: input.object,\n record_id: input.recordId,\n recipient_type: recipientType,\n recipient_id: input.recipientId,\n access_level: accessLevel,\n source,\n source_id: input.sourceId ?? null,\n granted_by: context.userId ?? null,\n reason: input.reason ?? null,\n created_at: now,\n updated_at: now,\n };\n await this.engine.insert('sys_record_share', row, { context: SYSTEM_CTX });\n return row as RecordShare;\n }\n\n /** Delete a share row by id. No-op when not found. */\n async revoke(shareId: string, _context: SharingExecutionContext): Promise<void> {\n if (!shareId) throw new Error('VALIDATION_FAILED: shareId is required');\n await this.engine.delete('sys_record_share', {\n where: { id: shareId },\n context: SYSTEM_CTX,\n });\n }\n\n /** List share rows for `(object, recordId)`. */\n async listShares(\n object: string,\n recordId: string,\n _context: SharingExecutionContext,\n ): Promise<RecordShare[]> {\n const rows = await this.engine.find('sys_record_share', {\n filter: { object_name: object, record_id: recordId },\n orderBy: [{ field: 'created_at', order: 'desc' }],\n limit: 500,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) ? (rows as RecordShare[]) : [];\n }\n\n // ── helpers ──────────────────────────────────────────────────────\n\n private shouldBypass(object: string, context: SharingExecutionContext): boolean {\n if (context?.isSystem) return true;\n if (this.bypassObjects.has(object)) return true;\n return false;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { ITeamGraphService } from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\ntype Cache = {\n expandUsers?: Map<string, string[]>;\n expandRole?: Map<string, string[]>;\n manager?: Map<string, string | null>;\n};\n\nexport interface TeamGraphOptions {\n engine: SharingEngine;\n /** Optional tenant scope; null means cross-tenant lookups. */\n organizationId?: string | null;\n /** Optional shared cache across one evaluator pass. */\n cache?: Cache;\n}\n\n/**\n * Default {@link ITeamGraphService} implementation backed by\n * `sys_team` + `sys_team_member` (better-auth's flat collaboration\n * grouping) plus `sys_member.role` for tenant role expansion.\n *\n * **This service does NOT walk a hierarchy.** Teams here are flat —\n * the enterprise org chart lives in `sys_department` and is served by\n * {@link DepartmentGraphService}.\n *\n * All queries elevate to {@link SYSTEM_CTX} since the graph is platform\n * metadata; callers (sharing rule evaluator, approval engine) own their\n * own enforcement.\n */\nexport class TeamGraphService implements ITeamGraphService {\n private readonly engine: SharingEngine;\n private readonly organizationId: string | null;\n private readonly cache: Cache;\n\n constructor(opts: TeamGraphOptions) {\n this.engine = opts.engine;\n this.organizationId = opts.organizationId ?? null;\n this.cache = opts.cache ?? {};\n this.cache.expandUsers ??= new Map();\n this.cache.expandRole ??= new Map();\n this.cache.manager ??= new Map();\n }\n\n async expandUsers(teamId: string): Promise<string[]> {\n if (!teamId) return [];\n const cached = this.cache.expandUsers!.get(teamId);\n if (cached) return cached;\n\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_team_member', {\n filter: { team_id: teamId },\n fields: ['user_id'],\n limit: 10000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n const users = Array.from(new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)));\n this.cache.expandUsers!.set(teamId, users);\n return users;\n }\n\n async expandRoleUsers(roleName: string, organizationId?: string): Promise<string[]> {\n if (!roleName) return [];\n const key = `${organizationId ?? this.organizationId ?? '*'}::${roleName}`;\n const cached = this.cache.expandRole!.get(key);\n if (cached) return cached;\n const filter: Record<string, unknown> = { role: roleName };\n const org = organizationId ?? this.organizationId;\n if (org) filter.organization_id = org;\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_member', {\n filter,\n fields: ['user_id'],\n limit: 10000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n const users = Array.from(new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)));\n this.cache.expandRole!.set(key, users);\n return users;\n }\n\n async managerOf(userId: string, _organizationId?: string): Promise<string | null> {\n if (!userId) return null;\n if (this.cache.manager!.has(userId)) return this.cache.manager!.get(userId) ?? null;\n let row: any = null;\n try {\n const rows = await this.engine.find('sys_user', {\n filter: { id: userId },\n fields: ['id', 'manager_id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n row = Array.isArray(rows) ? rows[0] : null;\n } catch {\n row = null;\n }\n const mgr = row?.manager_id ? String(row.manager_id) : null;\n this.cache.manager!.set(userId, mgr);\n return mgr;\n }\n}\n\n/**\n * Convenience helper used by the sharing-rule evaluator + approval\n * engine: expand an approver / recipient descriptor of the form\n * `{type, value}` into a flat list of user IDs by routing to the\n * appropriate graph service.\n *\n * `team` → flat team members (this service).\n * `department` → recursive department members (delegated; requires a\n * {@link IDepartmentGraphService} instance passed in `opts.dept`).\n * `role` → tenant role members.\n * `manager` → submitter's manager via `record[value] ?? record.owner_id`.\n * `field` → literal user id stored in `record[value]`.\n * `user` → literal value.\n * Anything else echoes `type:value` for back-compat with legacy\n * substring-match approver flows.\n */\nexport async function expandPrincipal(\n input: { type: string; value: string; record?: any },\n ctx: { team: TeamGraphService; dept?: { expandUsers(id: string): Promise<string[]> }; organizationId?: string | null },\n): Promise<string[]> {\n const t = input.type;\n const v = String(input.value ?? '');\n if (!v) return [];\n if (t === 'user') return [v];\n if (t === 'team') return ctx.team.expandUsers(v);\n if (t === 'department' || t === 'dept') {\n if (ctx.dept) return ctx.dept.expandUsers(v);\n return [`${t}:${v}`];\n }\n if (t === 'role') return ctx.team.expandRoleUsers(v, ctx.organizationId ?? undefined);\n if (t === 'field' && input.record) {\n const fv = (input.record as any)[v];\n return fv ? [String(fv)] : [];\n }\n if (t === 'manager' && input.record) {\n const subject = (input.record as any)[v] ?? (input.record as any).owner_id;\n if (!subject) return [];\n const mgr = await ctx.team.managerOf(String(subject), ctx.organizationId ?? undefined);\n return mgr ? [mgr] : [];\n }\n // queue / unknown — fall back to raw prefix string so existing\n // string-match approver flows keep working.\n return [`${t}:${v}`];\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { IDepartmentGraphService } from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\nimport { TeamGraphService } from './team-graph.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\ntype DeptCache = {\n descendants?: Map<string, string[]>;\n expandUsers?: Map<string, string[]>;\n head?: Map<string, string | null>;\n};\n\nexport interface DepartmentGraphOptions {\n engine: SharingEngine;\n /** Optional tenant scope; null means cross-tenant lookups. */\n organizationId?: string | null;\n /** Optional shared cache across one evaluator pass. */\n cache?: DeptCache;\n /**\n * Optional team-graph instance to share role / manager lookups with —\n * department graph proxies `managerOf` through so callers only need one\n * service.\n */\n teamGraph?: TeamGraphService;\n}\n\n/**\n * Default {@link IDepartmentGraphService} implementation.\n *\n * Walks `sys_department.parent_department_id` for hierarchy and\n * `sys_department_member` for member expansion. Treats the optional\n * `active` flag as a hard filter (inactive departments contribute no\n * members and stop BFS descent into their subtrees).\n *\n * Reuses {@link TeamGraphService.managerOf} for user-level manager\n * lookup so callers can use this single service in approval / sharing\n * pipelines.\n */\nexport class DepartmentGraphService implements IDepartmentGraphService {\n private readonly engine: SharingEngine;\n private readonly organizationId: string | null;\n private readonly cache: DeptCache;\n private readonly teamGraph?: TeamGraphService;\n\n constructor(opts: DepartmentGraphOptions) {\n this.engine = opts.engine;\n this.organizationId = opts.organizationId ?? null;\n this.cache = opts.cache ?? {};\n this.cache.descendants ??= new Map();\n this.cache.expandUsers ??= new Map();\n this.cache.head ??= new Map();\n this.teamGraph = opts.teamGraph;\n }\n\n async descendants(departmentId: string): Promise<string[]> {\n if (!departmentId) return [];\n const cached = this.cache.descendants!.get(departmentId);\n if (cached) return cached;\n\n // Verify seed itself is active + within tenant scope.\n let seedActive = true;\n try {\n const seedRows = await this.engine.find('sys_department', {\n filter: this.orgScope({ id: departmentId }),\n fields: ['id', 'active'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n const seedRow: any = Array.isArray(seedRows) ? seedRows[0] : null;\n if (!seedRow) seedActive = false;\n else if (seedRow.active === false) seedActive = false;\n } catch {\n seedActive = false;\n }\n if (!seedActive) {\n this.cache.descendants!.set(departmentId, []);\n return [];\n }\n\n const seen = new Set<string>([departmentId]);\n const queue: string[] = [departmentId];\n while (queue.length) {\n const parent = queue.shift()!;\n let children: any[] = [];\n try {\n children = await this.engine.find('sys_department', {\n filter: this.orgScope({ parent_department_id: parent, active: { $ne: false } }),\n fields: ['id'],\n limit: 1000,\n context: SYSTEM_CTX,\n });\n } catch {\n children = [];\n }\n for (const c of children ?? []) {\n const cid = String((c as any).id ?? '');\n if (cid && !seen.has(cid)) {\n seen.add(cid);\n queue.push(cid);\n }\n }\n }\n const out = Array.from(seen);\n this.cache.descendants!.set(departmentId, out);\n return out;\n }\n\n async expandUsers(departmentId: string): Promise<string[]> {\n if (!departmentId) return [];\n const cached = this.cache.expandUsers!.get(departmentId);\n if (cached) return cached;\n\n const depts = await this.descendants(departmentId);\n if (depts.length === 0) return [];\n\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_department_member', {\n filter: { department_id: { $in: depts } },\n fields: ['user_id'],\n limit: 10000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n const users = Array.from(\n new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)),\n );\n this.cache.expandUsers!.set(departmentId, users);\n return users;\n }\n\n async headOf(departmentId: string): Promise<string | null> {\n if (!departmentId) return null;\n if (this.cache.head!.has(departmentId)) return this.cache.head!.get(departmentId) ?? null;\n let row: any = null;\n try {\n const rows = await this.engine.find('sys_department', {\n filter: { id: departmentId },\n fields: ['id', 'manager_user_id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n row = Array.isArray(rows) ? rows[0] : null;\n } catch {\n row = null;\n }\n const head = row?.manager_user_id ? String(row.manager_user_id) : null;\n this.cache.head!.set(departmentId, head);\n return head;\n }\n\n async managerOf(userId: string, organizationId?: string): Promise<string | null> {\n if (this.teamGraph) return this.teamGraph.managerOf(userId, organizationId);\n // Standalone fallback: read sys_user.manager_id directly.\n if (!userId) return null;\n try {\n const rows = await this.engine.find('sys_user', {\n filter: { id: userId },\n fields: ['id', 'manager_id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n const row: any = Array.isArray(rows) ? rows[0] : null;\n return row?.manager_id ? String(row.manager_id) : null;\n } catch {\n return null;\n }\n }\n\n private orgScope(filter: Record<string, unknown>): Record<string, unknown> {\n if (this.organizationId) return { ...filter, organization_id: this.organizationId };\n return filter;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n ISharingRuleService,\n DefineSharingRuleInput,\n SharingRuleRow,\n SharingRuleEvaluationResult,\n SharingExecutionContext,\n ShareAccessLevel,\n SharingRuleRecipientType,\n} from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\nimport type { SharingService } from './sharing-service.js';\nimport { TeamGraphService } from './team-graph.js';\nimport { DepartmentGraphService } from './department-graph.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\nfunction uid(prefix: string): string {\n const g: any = globalThis as any;\n if (g.crypto?.randomUUID) return `${prefix}_${g.crypto.randomUUID()}`;\n return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction parseCriteria(raw: unknown): unknown | undefined {\n if (raw == null || raw === '') return undefined;\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n if (!trimmed) return undefined;\n try {\n return JSON.parse(trimmed);\n } catch {\n // Treat unparsable strings as opaque — most likely a CEL source\n // that v1's evaluator doesn't grok yet; rule will match nothing.\n return undefined;\n }\n }\n return raw;\n}\n\nfunction rowFromRule(row: any): SharingRuleRow {\n return {\n id: row.id,\n organization_id: row.organization_id ?? null,\n name: row.name,\n label: row.label,\n description: row.description ?? null,\n object_name: row.object_name,\n criteria: parseCriteria(row.criteria_json),\n recipient_type: row.recipient_type as SharingRuleRecipientType,\n recipient_id: row.recipient_id,\n access_level: row.access_level as ShareAccessLevel,\n active: row.active !== false,\n created_at: row.created_at ?? undefined,\n updated_at: row.updated_at ?? undefined,\n };\n}\n\nexport interface SharingRuleServiceOptions {\n engine: SharingEngine;\n sharing: SharingService;\n logger?: { info?: Function; warn?: Function; error?: Function; debug?: Function };\n}\n\n/**\n * Default {@link ISharingRuleService} implementation.\n *\n * Stores rule definitions in `sys_sharing_rule` and materialises grants\n * as `sys_record_share` rows with `source='rule'` and `source_id={ruleId}`\n * so reconcile can diff old grants vs fresh evaluation results without\n * touching manual / team-derived shares.\n */\nexport class SharingRuleService implements ISharingRuleService {\n private readonly engine: SharingEngine;\n private readonly sharing: SharingService;\n private readonly logger?: SharingRuleServiceOptions['logger'];\n\n constructor(opts: SharingRuleServiceOptions) {\n this.engine = opts.engine;\n this.sharing = opts.sharing;\n this.logger = opts.logger;\n }\n\n async defineRule(input: DefineSharingRuleInput, context: SharingExecutionContext): Promise<SharingRuleRow> {\n if (!input.name) throw new Error('VALIDATION_FAILED: name is required');\n if (!input.label) throw new Error('VALIDATION_FAILED: label is required');\n if (!input.object) throw new Error('VALIDATION_FAILED: object is required');\n if (!input.recipientType) throw new Error('VALIDATION_FAILED: recipientType is required');\n if (!input.recipientId) throw new Error('VALIDATION_FAILED: recipientId is required');\n\n const orgId = (context as any)?.organizationId ?? (context as any)?.tenantId ?? null;\n const now = new Date().toISOString();\n const accessLevel: ShareAccessLevel = input.accessLevel ?? 'read';\n const active = input.active !== false;\n const criteriaJson = input.criteria == null\n ? null\n : (typeof input.criteria === 'string' ? input.criteria : JSON.stringify(input.criteria));\n\n const existing = await this.engine.find('sys_sharing_rule', {\n filter: orgId ? { name: input.name, organization_id: orgId } : { name: input.name },\n limit: 1,\n context: SYSTEM_CTX,\n });\n if (Array.isArray(existing) && existing[0]) {\n const row: any = existing[0];\n const patch: any = {\n id: row.id,\n label: input.label,\n description: input.description ?? null,\n object_name: input.object,\n criteria_json: criteriaJson,\n recipient_type: input.recipientType,\n recipient_id: input.recipientId,\n access_level: accessLevel,\n active,\n updated_at: now,\n };\n await this.engine.update('sys_sharing_rule', patch, { context: SYSTEM_CTX });\n return rowFromRule({ ...row, ...patch });\n }\n\n const newRow: any = {\n id: uid('srule'),\n organization_id: orgId,\n name: input.name,\n label: input.label,\n description: input.description ?? null,\n object_name: input.object,\n criteria_json: criteriaJson,\n recipient_type: input.recipientType,\n recipient_id: input.recipientId,\n access_level: accessLevel,\n active,\n created_at: now,\n updated_at: now,\n };\n await this.engine.insert('sys_sharing_rule', newRow, { context: SYSTEM_CTX });\n return rowFromRule(newRow);\n }\n\n async listRules(\n filter: { object?: string; activeOnly?: boolean },\n context: SharingExecutionContext,\n ): Promise<SharingRuleRow[]> {\n const where: any = {};\n if (filter.object) where.object_name = filter.object;\n if (filter.activeOnly) where.active = true;\n const orgId = (context as any)?.organizationId ?? (context as any)?.tenantId;\n if (orgId) where.organization_id = orgId;\n const rows = await this.engine.find('sys_sharing_rule', {\n filter: where,\n orderBy: [{ field: 'name', order: 'asc' }],\n limit: 1000,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) ? rows.map(rowFromRule) : [];\n }\n\n async getRule(idOrName: string, context: SharingExecutionContext): Promise<SharingRuleRow | null> {\n if (!idOrName) return null;\n const orgId = (context as any)?.organizationId ?? (context as any)?.tenantId;\n const byId = await this.engine.find('sys_sharing_rule', {\n filter: { id: idOrName },\n limit: 1,\n context: SYSTEM_CTX,\n });\n if (Array.isArray(byId) && byId[0]) return rowFromRule(byId[0]);\n const byName = await this.engine.find('sys_sharing_rule', {\n filter: orgId ? { name: idOrName, organization_id: orgId } : { name: idOrName },\n limit: 1,\n context: SYSTEM_CTX,\n });\n if (Array.isArray(byName) && byName[0]) return rowFromRule(byName[0]);\n return null;\n }\n\n async deleteRule(idOrName: string, context: SharingExecutionContext): Promise<void> {\n const row = await this.getRule(idOrName, context);\n if (!row) return;\n // Drop materialised grants first so we don't orphan them.\n await this.engine.delete('sys_record_share', {\n where: { source: 'rule', source_id: row.id },\n context: SYSTEM_CTX,\n } as any);\n await this.engine.delete('sys_sharing_rule', {\n where: { id: row.id },\n context: SYSTEM_CTX,\n } as any);\n }\n\n async evaluateRule(idOrName: string, context: SharingExecutionContext): Promise<SharingRuleEvaluationResult> {\n const rule = await this.getRule(idOrName, context);\n if (!rule) throw new Error('RULE_NOT_FOUND');\n if (!rule.active) {\n // Inactive — purge any leftover grants and report revoke count.\n const revoked = await this.purgeRuleGrants(rule.id);\n return { ruleId: rule.id, matchedRecords: 0, expandedUsers: 0, grantsCreated: 0, grantsUpdated: 0, grantsRevoked: revoked };\n }\n const matches = await this.findMatchingRecords(rule);\n const users = await this.expandRecipient(rule);\n return this.reconcile(rule, matches, users);\n }\n\n async evaluateAllForRecord(\n object: string,\n recordId: string,\n context: SharingExecutionContext,\n ): Promise<SharingRuleEvaluationResult[]> {\n const rules = await this.listRules({ object, activeOnly: true }, context);\n if (rules.length === 0) return [];\n const results: SharingRuleEvaluationResult[] = [];\n for (const rule of rules) {\n const match = await this.recordMatches(rule, recordId);\n const users = match ? await this.expandRecipient(rule) : [];\n results.push(await this.reconcileForRecord(rule, recordId, match, users));\n }\n return results;\n }\n\n // ── internals ─────────────────────────────────────────────────────\n\n private async findMatchingRecords(rule: SharingRuleRow): Promise<string[]> {\n const filter = (rule.criteria ?? {}) as any;\n try {\n const rows = await this.engine.find(rule.object_name, {\n filter,\n fields: ['id'],\n limit: 5000,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) ? rows.map((r: any) => String(r.id)).filter(Boolean) : [];\n } catch (err: any) {\n this.logger?.warn?.('[sharing-rule] criteria query failed', { rule: rule.name, error: err?.message });\n return [];\n }\n }\n\n private async recordMatches(rule: SharingRuleRow, recordId: string): Promise<boolean> {\n const filter = { ...((rule.criteria ?? {}) as any), id: recordId };\n try {\n const rows = await this.engine.find(rule.object_name, {\n filter,\n fields: ['id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) && rows.length > 0;\n } catch {\n return false;\n }\n }\n\n private async expandRecipient(rule: SharingRuleRow): Promise<string[]> {\n const team = new TeamGraphService({\n engine: this.engine,\n organizationId: rule.organization_id ?? null,\n });\n if (rule.recipient_type === 'user') return [rule.recipient_id];\n if (rule.recipient_type === 'team') return team.expandUsers(rule.recipient_id);\n if (rule.recipient_type === 'department') {\n const dept = new DepartmentGraphService({\n engine: this.engine,\n organizationId: rule.organization_id ?? null,\n teamGraph: team,\n });\n return dept.expandUsers(rule.recipient_id);\n }\n if (rule.recipient_type === 'role') return team.expandRoleUsers(rule.recipient_id, rule.organization_id ?? undefined);\n // queue — v1 stores literal; treat as no-op until queue impl lands.\n return [];\n }\n\n private async reconcile(\n rule: SharingRuleRow,\n matchedIds: string[],\n users: string[],\n ): Promise<SharingRuleEvaluationResult> {\n const existing = await this.engine.find('sys_record_share', {\n filter: { source: 'rule', source_id: rule.id },\n fields: ['id', 'record_id', 'recipient_id', 'access_level'],\n limit: 100000,\n context: SYSTEM_CTX,\n });\n const desired = new Map<string, { record_id: string; recipient_id: string }>();\n for (const rid of matchedIds) {\n for (const uId of users) desired.set(`${rid}::${uId}`, { record_id: rid, recipient_id: uId });\n }\n const existingMap = new Map<string, any>();\n for (const row of (existing ?? [])) existingMap.set(`${row.record_id}::${row.recipient_id}`, row);\n\n let created = 0;\n let updated = 0;\n let revoked = 0;\n\n // Upsert desired.\n for (const [k, want] of desired.entries()) {\n const cur = existingMap.get(k);\n if (cur) {\n if (cur.access_level !== rule.access_level) {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId: want.record_id,\n recipientType: 'user',\n recipientId: want.recipient_id,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n updated += 1;\n }\n existingMap.delete(k);\n } else {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId: want.record_id,\n recipientType: 'user',\n recipientId: want.recipient_id,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n created += 1;\n }\n }\n // Revoke stale.\n for (const [, stale] of existingMap.entries()) {\n await this.sharing.revoke(stale.id, SYSTEM_CTX as any);\n revoked += 1;\n }\n\n return {\n ruleId: rule.id,\n matchedRecords: matchedIds.length,\n expandedUsers: users.length,\n grantsCreated: created,\n grantsUpdated: updated,\n grantsRevoked: revoked,\n };\n }\n\n private async reconcileForRecord(\n rule: SharingRuleRow,\n recordId: string,\n match: boolean,\n users: string[],\n ): Promise<SharingRuleEvaluationResult> {\n const existing = await this.engine.find('sys_record_share', {\n filter: { source: 'rule', source_id: rule.id, record_id: recordId },\n fields: ['id', 'record_id', 'recipient_id', 'access_level'],\n limit: 1000,\n context: SYSTEM_CTX,\n });\n const existingMap = new Map<string, any>();\n for (const row of (existing ?? [])) existingMap.set(String(row.recipient_id), row);\n\n let created = 0;\n let updated = 0;\n let revoked = 0;\n\n if (match) {\n for (const userId of users) {\n const cur = existingMap.get(userId);\n if (cur) {\n if (cur.access_level !== rule.access_level) {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId,\n recipientType: 'user',\n recipientId: userId,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n updated += 1;\n }\n existingMap.delete(userId);\n } else {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId,\n recipientType: 'user',\n recipientId: userId,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n created += 1;\n }\n }\n }\n // Anything still in existingMap is stale (either match=false or\n // user no longer in expanded set).\n for (const [, stale] of existingMap.entries()) {\n await this.sharing.revoke(stale.id, SYSTEM_CTX as any);\n revoked += 1;\n }\n\n return {\n ruleId: rule.id,\n matchedRecords: match ? 1 : 0,\n expandedUsers: users.length,\n grantsCreated: created,\n grantsUpdated: updated,\n grantsRevoked: revoked,\n };\n }\n\n private async purgeRuleGrants(ruleId: string): Promise<number> {\n const existing = await this.engine.find('sys_record_share', {\n filter: { source: 'rule', source_id: ruleId },\n fields: ['id'],\n limit: 100000,\n context: SYSTEM_CTX,\n });\n let revoked = 0;\n for (const row of (existing ?? [])) {\n await this.sharing.revoke((row as any).id, SYSTEM_CTX as any);\n revoked += 1;\n }\n return revoked;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n IShareLinkService,\n ShareLink,\n CreateShareLinkInput,\n ListShareLinksFilter,\n ResolveShareLinkResult,\n ShareLinkExecutionContext,\n ShareLinkPermission,\n ShareLinkAudience,\n} from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\n\n/** Service-elevated context for the plugin's own queries / mutations. */\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\n/** URL-safe alphabet (RFC 4648 base64url minus padding). 64 symbols. */\nconst TOKEN_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n/** ~144 bits of entropy at 24 chars — well above the OWASP recommendation. */\nconst TOKEN_LENGTH = 24;\n\n/** Default value when no per-object cap is configured. */\nconst DEFAULT_MAX_EXPIRY_DAYS = 365;\n\n/**\n * Generate a URL-safe token. Uses `crypto.getRandomValues` when present\n * (browsers, Node ≥ 19) and falls back to `Math.random` only for the\n * pathological case of a polyfill-less old runtime. The fallback is\n * still ≥ 100 bits of entropy because of TOKEN_LENGTH.\n */\nfunction generateToken(length: number = TOKEN_LENGTH): string {\n const g: any = globalThis as any;\n const bytes = new Uint8Array(length);\n if (g.crypto?.getRandomValues) {\n g.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n let out = '';\n for (let i = 0; i < length; i++) {\n out += TOKEN_ALPHABET[bytes[i] % TOKEN_ALPHABET.length];\n }\n return out;\n}\n\n/** Internal helper — extract publicSharing policy from an object schema. */\nfunction getPolicy(schema: any): {\n enabled: boolean;\n allowedAudiences: ShareLinkAudience[];\n allowedPermissions: ShareLinkPermission[];\n maxExpiryDays?: number;\n redactFields: string[];\n} {\n const raw = schema?.publicSharing;\n if (!raw || raw.enabled !== true) {\n return {\n enabled: false,\n allowedAudiences: [],\n allowedPermissions: [],\n redactFields: [],\n };\n }\n return {\n enabled: true,\n allowedAudiences: (raw.allowedAudiences as ShareLinkAudience[] | undefined) ?? ['link_only'],\n allowedPermissions: (raw.allowedPermissions as ShareLinkPermission[] | undefined) ?? ['view'],\n maxExpiryDays: typeof raw.maxExpiryDays === 'number' ? raw.maxExpiryDays : undefined,\n redactFields: Array.isArray(raw.redactFields) ? (raw.redactFields as string[]) : [],\n };\n}\n\n/** Parse `expiresAt` as either an ISO string or a relative duration like \"7d\", \"24h\", \"30m\". */\nfunction normaliseExpiresAt(input: string | null | undefined, maxDays: number): string | null {\n if (!input) return null;\n const now = Date.now();\n const cap = now + maxDays * 86_400_000;\n\n // Relative duration shorthand.\n const m = /^([0-9]+)(s|m|h|d)$/i.exec(input);\n if (m) {\n const n = Number(m[1]);\n const unit = m[2].toLowerCase();\n const ms = unit === 's' ? n * 1000 : unit === 'm' ? n * 60_000 : unit === 'h' ? n * 3_600_000 : n * 86_400_000;\n const at = now + ms;\n if (at > cap) {\n throw makeError(422, 'EXPIRY_TOO_LONG', `expiresAt exceeds the object's max of ${maxDays} days`);\n }\n return new Date(at).toISOString();\n }\n\n // Otherwise expect an ISO timestamp.\n const t = Date.parse(input);\n if (Number.isNaN(t)) {\n throw makeError(422, 'INVALID_EXPIRY', `expiresAt is not a valid ISO timestamp or duration: ${input}`);\n }\n if (t > cap) {\n throw makeError(422, 'EXPIRY_TOO_LONG', `expiresAt exceeds the object's max of ${maxDays} days`);\n }\n if (t <= now) {\n throw makeError(422, 'EXPIRY_IN_PAST', 'expiresAt must be in the future');\n }\n return new Date(t).toISOString();\n}\n\n/**\n * Weak password hash. Production deployments should swap in argon2 /\n * bcrypt via dependency injection (see `ShareLinkServiceOptions.hashPassword`).\n * The default uses SubtleCrypto SHA-256 with a per-row salt — strong\n * enough to keep the hash useless to a casual observer and to deflate\n * the cost of a database leak, but NOT a substitute for argon2 against\n * a determined attacker. The platform deliberately surfaces this in the\n * plugin docs so deployments can decide.\n */\nasync function defaultHashPassword(password: string): Promise<string> {\n const g: any = globalThis as any;\n const subtle = g.crypto?.subtle;\n const salt = generateToken(16);\n if (!subtle) {\n // Synthetic fallback — no SubtleCrypto means we're in a stripped\n // runtime; emit a clearly-marked placeholder so the deployment is\n // forced to wire in a real hasher rather than ship a weak one.\n return `weak$${salt}$${password}`;\n }\n const enc = new TextEncoder();\n const buf = await subtle.digest('SHA-256', enc.encode(salt + ':' + password));\n const hex = Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `sha256$${salt}$${hex}`;\n}\n\nasync function defaultVerifyPassword(password: string, hash: string): Promise<boolean> {\n if (hash.startsWith('weak$')) {\n const [, , stored] = hash.split('$');\n return stored === password;\n }\n if (hash.startsWith('sha256$')) {\n const [, salt, expected] = hash.split('$');\n const g: any = globalThis as any;\n const subtle = g.crypto?.subtle;\n if (!subtle) return false;\n const enc = new TextEncoder();\n const buf = await subtle.digest('SHA-256', enc.encode(salt + ':' + password));\n const hex = Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return hex === expected;\n }\n return false;\n}\n\nfunction makeError(status: number, code: string, message: string): Error {\n const err: any = new Error(message);\n err.status = status;\n err.code = code;\n return err;\n}\n\nexport interface ShareLinkServiceOptions {\n engine: SharingEngine;\n /** Override the default SHA-256 hasher with argon2 / bcrypt for production. */\n hashPassword?: (plain: string) => Promise<string>;\n /** Companion verifier — must accept hashes produced by `hashPassword`. */\n verifyPassword?: (plain: string, hash: string) => Promise<boolean>;\n /**\n * Bypass the per-object opt-in check (useful when the schema scan is\n * happening after `start`). When omitted, calls against an object\n * without `publicSharing.enabled=true` are rejected with 422.\n */\n permissive?: boolean;\n}\n\n/**\n * Default `IShareLinkService` implementation.\n *\n * Persists every link in `sys_share_link`. The companion REST routes\n * (`registerShareLinkRoutes`) thin-wrap the service; the public\n * `/api/v1/share-links/:token` route resolves and re-injects the\n * \"share-link principal\" into the execution context so the standard\n * data middleware can authorise the downstream read.\n */\nexport class ShareLinkService implements IShareLinkService {\n private readonly engine: SharingEngine;\n private readonly permissive: boolean;\n private readonly hashPassword: (plain: string) => Promise<string>;\n private readonly verifyPassword: (plain: string, hash: string) => Promise<boolean>;\n\n constructor(opts: ShareLinkServiceOptions) {\n this.engine = opts.engine;\n this.permissive = opts.permissive ?? false;\n this.hashPassword = opts.hashPassword ?? defaultHashPassword;\n this.verifyPassword = opts.verifyPassword ?? defaultVerifyPassword;\n }\n\n async createLink(\n input: CreateShareLinkInput,\n context: ShareLinkExecutionContext,\n ): Promise<ShareLink> {\n if (!input.object) throw makeError(400, 'VALIDATION_FAILED', 'object is required');\n if (!input.recordId) throw makeError(400, 'VALIDATION_FAILED', 'recordId is required');\n\n const schema = this.engine.getSchema?.(input.object);\n const policy = getPolicy(schema);\n\n if (!policy.enabled && !this.permissive && !context.isSystem) {\n throw makeError(\n 422,\n 'SHARING_NOT_ENABLED',\n `Object '${input.object}' has not enabled publicSharing in its schema`,\n );\n }\n\n const permission: ShareLinkPermission = input.permission ?? 'view';\n if (policy.enabled && policy.allowedPermissions.length > 0 && !policy.allowedPermissions.includes(permission)) {\n throw makeError(\n 422,\n 'PERMISSION_NOT_ALLOWED',\n `Object '${input.object}' does not allow share permission '${permission}'. Allowed: ${policy.allowedPermissions.join(', ')}`,\n );\n }\n\n const audience: ShareLinkAudience = input.audience ?? 'link_only';\n if (policy.enabled && policy.allowedAudiences.length > 0 && !policy.allowedAudiences.includes(audience)) {\n throw makeError(\n 422,\n 'AUDIENCE_NOT_ALLOWED',\n `Object '${input.object}' does not allow audience '${audience}'. Allowed: ${policy.allowedAudiences.join(', ')}`,\n );\n }\n\n if (audience === 'email' && (!input.emailAllowlist || input.emailAllowlist.length === 0)) {\n throw makeError(400, 'VALIDATION_FAILED', 'emailAllowlist is required when audience=email');\n }\n\n // Confirm the target record actually exists — silently issuing\n // links against ghost rows is a footgun.\n const exists = await this.engine.find(input.object, {\n where: { id: input.recordId },\n fields: ['id'],\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n if (!Array.isArray(exists) || exists.length === 0) {\n throw makeError(404, 'RECORD_NOT_FOUND', `${input.object}/${input.recordId} does not exist`);\n }\n\n const maxDays = policy.maxExpiryDays ?? DEFAULT_MAX_EXPIRY_DAYS;\n const expires_at = normaliseExpiresAt(input.expiresAt, maxDays);\n\n const passwordHash = input.password ? await this.hashPassword(input.password) : null;\n\n const row: ShareLink = {\n id: `shl_${generateToken(16)}`,\n token: generateToken(TOKEN_LENGTH),\n object_name: input.object,\n record_id: input.recordId,\n permission,\n audience,\n expires_at,\n email_allowlist:\n input.emailAllowlist && input.emailAllowlist.length > 0\n ? input.emailAllowlist.map((e) => e.trim().toLowerCase()).filter(Boolean)\n : null,\n password_hash: passwordHash,\n redact_fields: input.redactFields && input.redactFields.length > 0 ? input.redactFields : null,\n label: input.label ?? null,\n revoked_at: null,\n created_by: context.userId ?? null,\n created_at: new Date().toISOString(),\n last_used_at: null,\n use_count: 0,\n };\n\n await this.engine.insert('sys_share_link', row, { context: SYSTEM_CTX });\n return row;\n }\n\n async revokeLink(idOrToken: string, _context: ShareLinkExecutionContext): Promise<void> {\n if (!idOrToken) throw makeError(400, 'VALIDATION_FAILED', 'id or token is required');\n const filter = idOrToken.startsWith('shl_') ? { id: idOrToken } : { token: idOrToken };\n const rows = await this.engine.find('sys_share_link', {\n where: filter,\n fields: ['id', 'revoked_at'],\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const row = Array.isArray(rows) ? (rows[0] as any) : undefined;\n if (!row) return; // No-op when missing\n if (row.revoked_at) return; // Already revoked\n await this.engine.update(\n 'sys_share_link',\n { id: row.id, revoked_at: new Date().toISOString() },\n { context: SYSTEM_CTX },\n );\n }\n\n async listLinks(\n filter: ListShareLinksFilter,\n context: ShareLinkExecutionContext,\n ): Promise<ShareLink[]> {\n const where: Record<string, unknown> = {};\n if (filter.object) where.object_name = filter.object;\n if (filter.recordId) where.record_id = filter.recordId;\n if (filter.createdBy) where.created_by = filter.createdBy;\n if (!filter.includeRevoked) where.revoked_at = null;\n\n const rows = await this.engine.find('sys_share_link', {\n where,\n limit: 200,\n sort: [{ field: 'created_at', order: 'desc' }],\n context: context.isSystem ? SYSTEM_CTX : context,\n } as any);\n return Array.isArray(rows) ? (rows as ShareLink[]) : [];\n }\n\n async resolveToken(\n token: string,\n probe: { signedInUserId?: string; recipientEmail?: string; providedPassword?: string } = {},\n ): Promise<ResolveShareLinkResult | null> {\n if (!token || typeof token !== 'string' || token.length < 8) return null;\n\n const rows = await this.engine.find('sys_share_link', {\n where: { token },\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const row = Array.isArray(rows) ? (rows[0] as ShareLink | undefined) : undefined;\n if (!row) return null;\n\n if (row.revoked_at) return null;\n if (row.expires_at && Date.parse(row.expires_at) <= Date.now()) return null;\n\n // Audience gating.\n if (row.audience === 'signed_in' && !probe.signedInUserId) return null;\n if (row.audience === 'email') {\n const allow = row.email_allowlist ?? [];\n const supplied = (probe.recipientEmail ?? '').trim().toLowerCase();\n if (!supplied || !allow.includes(supplied)) return null;\n }\n\n if (row.password_hash) {\n if (!probe.providedPassword) return null;\n const ok = await this.verifyPassword(probe.providedPassword, row.password_hash);\n if (!ok) return null;\n }\n\n // Compute the effective redaction set (object default ∪ per-link).\n const schema = this.engine.getSchema?.(row.object_name);\n const policy = getPolicy(schema);\n const redactFields = Array.from(\n new Set<string>([...(policy.redactFields ?? []), ...((row.redact_fields as string[]) ?? [])]),\n );\n\n // Stamp usage. Errors here MUST NOT block the read — log-and-continue.\n try {\n await this.engine.update(\n 'sys_share_link',\n {\n id: row.id,\n last_used_at: new Date().toISOString(),\n use_count: (row.use_count ?? 0) + 1,\n },\n { context: SYSTEM_CTX },\n );\n } catch {\n // best-effort — usage telemetry is a nice-to-have\n }\n\n return { link: row, redactFields };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * REST surface for ShareLinkService.\n *\n * POST /api/v1/share-links → create a link\n * GET /api/v1/share-links → list links (?object, ?recordId, ?includeRevoked)\n * DELETE /api/v1/share-links/:idOrToken → revoke\n * GET /api/v1/share-links/:token/resolve → resolve token, returns { record, link, redactFields }\n *\n * The resolve route is intentionally public — it's the only endpoint\n * holders of a token need. It does:\n *\n * 1. Look up the row by token (via ShareLinkService.resolveToken,\n * which gates audience / expiry / password and stamps usage).\n * 2. Fetch the underlying record with a SYSTEM context (so the read\n * bypasses normal RLS — the token IS the authorisation).\n * 3. Strip `redactFields` from the record before returning.\n *\n * For browser-rendered share pages, the front-end calls this endpoint\n * and renders the response read-only.\n */\n\nimport type { IHttpServer, IHttpRequest, IHttpResponse, RouteHandler } from '@objectstack/spec/contracts';\nimport type { ShareLinkExecutionContext } from '@objectstack/spec/contracts';\nimport type { ShareLinkService } from './share-link-service.js';\nimport type { SharingEngine } from './sharing-service.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\nexport interface ShareLinkRoutesOptions {\n basePath?: string;\n /** Read caller identity for authenticated routes. */\n contextFromRequest?: (req: IHttpRequest) => ShareLinkExecutionContext;\n}\n\nconst defaultContext = (req: IHttpRequest): ShareLinkExecutionContext => {\n const header = (name: string): string | undefined => {\n const v = req.headers?.[name];\n return Array.isArray(v) ? v[0] : v;\n };\n return {\n userId: header('x-user-id'),\n tenantId: header('x-tenant-id'),\n };\n};\n\nfunction sendError(res: IHttpResponse, status: number, code: string, message: string) {\n res.status(status).json({ error: { code, message } });\n}\n\n/** Strip `redactFields` from a record (also removes from nested arrays of objects). */\nfunction applyRedaction(record: any, redactFields: string[]): any {\n if (!record || typeof record !== 'object' || redactFields.length === 0) return record;\n if (Array.isArray(record)) return record.map((r) => applyRedaction(r, redactFields));\n const out: any = {};\n for (const [k, v] of Object.entries(record)) {\n if (redactFields.includes(k)) continue;\n out[k] = v;\n }\n return out;\n}\n\nexport function registerShareLinkRoutes(\n http: IHttpServer,\n service: ShareLinkService,\n engine: SharingEngine,\n opts: ShareLinkRoutesOptions = {},\n): void {\n const base = opts.basePath ?? '/api/v1/share-links';\n const ctxOf = opts.contextFromRequest ?? defaultContext;\n\n // ── CREATE ─────────────────────────────────────────────────────\n http.post(base, (async (req, res) => {\n try {\n const ctx = ctxOf(req);\n const body: any = req.body ?? {};\n if (!body.object || !body.recordId) {\n return sendError(res, 400, 'VALIDATION_FAILED', 'object and recordId are required');\n }\n const link = await service.createLink(\n {\n object: body.object,\n recordId: body.recordId,\n permission: body.permission,\n audience: body.audience,\n expiresAt: body.expiresAt ?? null,\n emailAllowlist: body.emailAllowlist,\n password: body.password,\n redactFields: body.redactFields,\n label: body.label,\n },\n ctx,\n );\n // Echo the token in the create response only — the listing\n // endpoint also returns it (admins need to copy/recreate URLs),\n // but downstream API consumers typically derive the public URL\n // from `link.token` immediately.\n await res.status(201).json({ link });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to create link');\n }\n }) satisfies RouteHandler);\n\n // ── LIST ───────────────────────────────────────────────────────\n http.get(base, (async (req, res) => {\n try {\n const ctx = ctxOf(req);\n const q = req.query ?? {};\n const link = await service.listLinks(\n {\n object: typeof q.object === 'string' ? q.object : undefined,\n recordId: typeof q.recordId === 'string' ? q.recordId : undefined,\n createdBy: typeof q.createdBy === 'string' ? q.createdBy : undefined,\n includeRevoked: q.includeRevoked === 'true' || q.includeRevoked === '1',\n },\n ctx,\n );\n await res.json({ links: link });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to list links');\n }\n }) satisfies RouteHandler);\n\n // ── REVOKE ─────────────────────────────────────────────────────\n http.delete(`${base}/:idOrToken`, (async (req, res) => {\n try {\n const ctx = ctxOf(req);\n await service.revokeLink(req.params.idOrToken, ctx);\n await res.status(200).json({ ok: true });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to revoke link');\n }\n }) satisfies RouteHandler);\n\n // ── PUBLIC RESOLVE ────────────────────────────────────────────\n //\n // No `ctxOf` here — the token IS the authorisation. We still allow\n // probes from a signed-in user so audience=signed_in is satisfiable.\n http.get(`${base}/:token/resolve`, (async (req, res) => {\n try {\n const q = req.query ?? {};\n const signedInUserId = (() => {\n const v = req.headers?.['x-user-id'];\n return Array.isArray(v) ? v[0] : v;\n })();\n const recipientEmail = typeof q.email === 'string' ? q.email : undefined;\n const providedPassword =\n typeof q.password === 'string'\n ? q.password\n : (() => {\n const v = req.headers?.['x-share-password'];\n return Array.isArray(v) ? v[0] : v;\n })();\n\n const resolved = await service.resolveToken(req.params.token, {\n signedInUserId,\n recipientEmail,\n providedPassword,\n });\n if (!resolved) {\n // Probe row to give a more useful status code (401 vs 404 vs 410).\n const probe = await engine.find('sys_share_link', {\n where: { token: req.params.token },\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const row = Array.isArray(probe) && probe[0] ? (probe[0] as any) : null;\n if (row && !row.revoked_at && (!row.expires_at || Date.parse(row.expires_at) > Date.now())) {\n if (row.password_hash) {\n return sendError(\n res,\n 401,\n providedPassword ? 'WRONG_PASSWORD' : 'NEEDS_PASSWORD',\n providedPassword ? 'Incorrect password' : 'This link requires a password',\n );\n }\n if (row.audience === 'signed_in' && !signedInUserId) {\n return sendError(res, 401, 'SIGN_IN_REQUIRED', 'Please sign in to view this link');\n }\n }\n if (row && (row.revoked_at || (row.expires_at && Date.parse(row.expires_at) <= Date.now()))) {\n return sendError(res, 410, 'EXPIRED_OR_REVOKED', 'Share link has expired or been revoked');\n }\n return sendError(res, 404, 'INVALID_OR_EXPIRED', 'Share link is invalid, expired, or revoked');\n }\n\n // Fetch the underlying record with system context — the token\n // gates access, RLS does not.\n const rows = await engine.find(resolved.link.object_name, {\n where: { id: resolved.link.record_id },\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const record = Array.isArray(rows) && rows[0] ? rows[0] : null;\n if (!record) {\n return sendError(res, 410, 'RECORD_GONE', 'The shared record no longer exists');\n }\n\n await res.json({\n record: applyRedaction(record, resolved.redactFields),\n link: {\n id: resolved.link.id,\n token: resolved.link.token,\n object_name: resolved.link.object_name,\n record_id: resolved.link.record_id,\n permission: resolved.link.permission,\n audience: resolved.link.audience,\n expires_at: resolved.link.expires_at,\n label: resolved.link.label,\n created_at: resolved.link.created_at,\n },\n redactFields: resolved.redactFields,\n });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to resolve link');\n }\n }) satisfies RouteHandler);\n\n // ──────────────────────────────────────────────────────────────\n // Object-specific related-records lookup.\n //\n // Some objects only make sense alongside their children — most\n // notably `ai_conversations` and the `ai_messages` they own. Rather\n // than baking every relationship into the resolver, we expose a\n // narrow, opt-in `GET /:token/messages` route that:\n //\n // 1. Re-validates the capability token (so revocation / expiry\n // kicks in even after the original resolve).\n // 2. Confirms the shared record really is an `ai_conversations`.\n // 3. Returns the conversation's messages, ordered by creation.\n //\n // Other object kinds can register additional public endpoints\n // following the same pattern.\n // ──────────────────────────────────────────────────────────────\n http.get(`${base}/:token/messages`, (async (req, res) => {\n try {\n const password =\n typeof req.query?.password === 'string' ? (req.query.password as string) : undefined;\n const resolved = await service.resolveToken(req.params.token, { providedPassword: password });\n if (!resolved) {\n sendError(res, 404, 'NOT_FOUND', 'Share link not found');\n return;\n }\n if (resolved.link.object_name !== 'ai_conversations') {\n sendError(res, 400, 'UNSUPPORTED', 'This share link does not expose messages');\n return;\n }\n const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n const rows = await engine.find('ai_messages', {\n where: { conversation_id: resolved.link.record_id },\n sort: [{ field: 'created_at', order: 'asc' }],\n limit: 500,\n context: SYSTEM_CTX,\n } as any);\n res.status(200).json({ data: rows ?? [] });\n } catch (err: any) {\n sendError(\n res,\n err?.status ?? 500,\n err?.code ?? 'INTERNAL',\n err?.message ?? 'Failed to load messages',\n );\n }\n }) satisfies RouteHandler);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { SharingRuleService } from './sharing-rule-service.js';\nimport type { SharingRuleRow } from '@objectstack/spec/contracts';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\nexport const SHARING_RULE_HOOK_PACKAGE = 'plugin-sharing:rules';\n\ninterface MinimalEngine {\n registerHook(event: string, handler: (ctx: any) => any | Promise<any>, options?: {\n object?: string | string[];\n priority?: number;\n packageId?: string;\n }): void;\n unregisterHooksByPackage(packageId: string): number;\n}\n\ninterface MinimalLogger {\n info?: (msg: any, ...rest: any[]) => void;\n warn?: (msg: any, ...rest: any[]) => void;\n}\n\n/**\n * Bind afterInsert/afterUpdate hooks for every distinct object_name in\n * `rules`. Each hook calls `service.evaluateAllForRecord(object, id, …)`\n * with SYSTEM_CTX so the evaluator can write `sys_record_share` rows\n * without being blocked by its own enforcement.\n *\n * Caller is responsible for invoking {@link unbindAllRuleHooks} before\n * re-binding when the rule set changes.\n */\nexport function bindRuleHooks(\n engine: MinimalEngine,\n service: SharingRuleService,\n rules: SharingRuleRow[],\n logger?: MinimalLogger,\n): void {\n const objects = new Set<string>();\n for (const r of rules) {\n if (r.active === false) continue;\n if (r.object_name) objects.add(r.object_name);\n }\n for (const objectName of objects) {\n const handler = async (ctx: any) => {\n if ((ctx?.session as any)?.isSystem) return;\n try {\n const data = ctx?.result ?? ctx?.input?.data ?? {};\n const id = String((data as any)?.id ?? ctx?.input?.id ?? '');\n if (!id) return;\n await service.evaluateAllForRecord(objectName, id, SYSTEM_CTX as any);\n } catch (err: any) {\n logger?.warn?.('[sharing-rule] hook evaluation failed', { object: objectName, error: err?.message });\n }\n };\n engine.registerHook('afterInsert', handler, { object: objectName, packageId: SHARING_RULE_HOOK_PACKAGE, priority: 180 });\n engine.registerHook('afterUpdate', handler, { object: objectName, packageId: SHARING_RULE_HOOK_PACKAGE, priority: 180 });\n }\n logger?.info?.('[sharing-rule] hooks bound', { objects: Array.from(objects), ruleCount: rules.length });\n}\n\nexport function unbindAllRuleHooks(engine: MinimalEngine): number {\n return engine.unregisterHooksByPackage(SHARING_RULE_HOOK_PACKAGE);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport type { EngineMiddleware, OperationContext } from '@objectstack/objectql';\nimport type { IHttpServer } from '@objectstack/spec/contracts';\nimport { SysRecordShare, SysSharingRule, SysShareLink } from './objects/index.js';\nimport { SysDepartment, SysDepartmentMember } from '@objectstack/platform-objects/identity';\nimport { SharingService, type SharingEngine } from './sharing-service.js';\nimport { SharingRuleService } from './sharing-rule-service.js';\nimport { ShareLinkService } from './share-link-service.js';\nimport { registerShareLinkRoutes } from './share-link-routes.js';\nimport { bindRuleHooks, unbindAllRuleHooks } from './rule-hooks.js';\n\nexport interface SharingPluginOptions {\n /** Extra object names that bypass sharing entirely. */\n bypassObjects?: string[];\n /**\n * Disable enforcement (read filter + canEdit) while still registering\n * the schema + service. Useful in development to flip enforcement on\n * via env var without rebuilding.\n */\n enforce?: boolean;\n /**\n * Disable the public share-link REST routes. The `IShareLinkService`\n * is always registered (other services may depend on it); only the\n * HTTP surface is suppressed.\n */\n registerShareLinkRoutes?: boolean;\n /**\n * Base path for the share-link REST surface. Defaults to\n * `/api/v1/share-links`.\n */\n shareLinkBasePath?: string;\n}\n\n/**\n * SharingServicePlugin — registers `sys_record_share`, the `sharing`\n * service, and the engine middleware that enforces\n * `object.sharingModel`.\n *\n * Enforcement is opt-in per object:\n *\n * - `sharingModel: 'private'` → reads filtered to `(owner_id == me) OR\n * (record explicitly shared with me)`. Writes require ownership or\n * an `edit`/`full` share.\n * - `sharingModel: 'read'` → reads unrestricted; writes gated as\n * above (typical \"everyone can see, only owner can edit\").\n * - any other value (or no value) → no enforcement. This keeps\n * existing CRM behaviour identical until admins explicitly enable\n * sharing on a per-object basis.\n *\n * @example\n * ```ts\n * import { SharingServicePlugin } from '@objectstack/plugin-sharing';\n *\n * kernel.use(new SharingServicePlugin());\n *\n * // Mark an object private — middleware enforces from this point on.\n * defineObject({\n * name: 'account',\n * sharingModel: 'private',\n * fields: { owner_id: Field.lookup('sys_user'), ... },\n * });\n * ```\n */\nexport class SharingServicePlugin implements Plugin {\n name = 'com.objectstack.service.sharing';\n version = '1.0.0';\n type = 'standard';\n dependencies = ['com.objectstack.engine.objectql'];\n\n private readonly options: SharingPluginOptions;\n private service?: SharingService;\n private ruleService?: SharingRuleService;\n private linkService?: ShareLinkService;\n\n constructor(options: SharingPluginOptions = {}) {\n this.options = options;\n }\n\n async init(ctx: PluginContext): Promise<void> {\n // Register sys_record_share via the manifest service.\n ctx.getService<{ register(m: any): void }>('manifest').register({\n id: 'com.objectstack.service.sharing',\n name: 'Sharing Service',\n version: '1.0.0',\n type: 'plugin',\n scope: 'system',\n defaultDatasource: 'cloud',\n namespace: 'sys',\n objects: [SysRecordShare, SysSharingRule, SysDepartment, SysDepartmentMember, SysShareLink],\n // ADR-0029 D7 — contribute the sharing entries into the Setup app's\n // `group_access_control` slot (priority 200 so they sit after plugin-\n // security's Roles / Permission Sets). This plugin owns these objects (K2).\n navigationContributions: [\n {\n app: 'setup',\n group: 'group_access_control',\n priority: 200,\n items: [\n { id: 'nav_sharing_rules', type: 'object', label: 'Sharing Rules', objectName: 'sys_sharing_rule', icon: 'share-2', requiresObject: 'sys_sharing_rule', requiredPermissions: ['manage_platform_settings'] },\n { id: 'nav_record_shares', type: 'object', label: 'Record Shares', objectName: 'sys_record_share', icon: 'link', requiresObject: 'sys_record_share', requiredPermissions: ['manage_platform_settings'] },\n ],\n },\n ],\n });\n\n // ADR-0029 D8 — contribute this plugin's object translations to the i18n\n // service on kernel:ready (the i18n plugin may register after this one).\n if (typeof (ctx as any).hook === 'function') {\n (ctx as any).hook('kernel:ready', async () => {\n try {\n const i18n = ctx.getService<any>('i18n');\n if (i18n && typeof i18n.loadTranslations === 'function') {\n const { SharingTranslations } = await import('./translations/index.js');\n for (const [locale, data] of Object.entries(SharingTranslations)) {\n i18n.loadTranslations(locale, data as Record<string, unknown>);\n }\n }\n } catch { /* i18n optional */ }\n });\n }\n ctx.logger.info('SharingServicePlugin: schema registered');\n }\n\n async start(ctx: PluginContext): Promise<void> {\n ctx.hook('kernel:ready', async () => {\n let engine: any = null;\n try { engine = ctx.getService<any>('objectql'); }\n catch { try { engine = ctx.getService<any>('data'); } catch { /* ignore */ } }\n if (!engine) {\n ctx.logger.warn('SharingServicePlugin: no ObjectQL engine — service NOT registered');\n return;\n }\n\n this.service = new SharingService({\n engine: engine as SharingEngine,\n bypassObjects: this.options.bypassObjects,\n });\n ctx.registerService('sharing', this.service);\n\n // Enforcement (read-filter middleware + sharing-rule hooks) is opt-out\n // via `enforce: false`. The share-link service below is registered\n // REGARDLESS — capability-token sharing does not depend on principal-\n // based RLS enforcement, and multi-tenant hosts mount this plugin purely\n // for the `shareLinks` service (per-env enforcement is applied elsewhere).\n if (this.options.enforce === false) {\n ctx.logger.info('SharingServicePlugin: enforcement disabled (enforce=false) — share-link service still registered');\n } else {\n const mw = buildSharingMiddleware(this.service);\n if (typeof engine.registerMiddleware === 'function') {\n engine.registerMiddleware(mw, { object: '*' });\n ctx.logger.info('SharingServicePlugin: enforcement middleware installed');\n } else {\n ctx.logger.warn('SharingServicePlugin: engine has no registerMiddleware — enforcement not applied');\n }\n\n // Rule evaluator + hot-rebindable lifecycle hooks.\n try {\n this.ruleService = new SharingRuleService({\n engine: engine as SharingEngine,\n sharing: this.service,\n logger: ctx.logger as any,\n });\n ctx.registerService('sharingRules', this.ruleService);\n\n if (typeof engine.registerHook === 'function' && typeof engine.unregisterHooksByPackage === 'function') {\n const rules = await this.ruleService.listRules({ activeOnly: true }, { isSystem: true } as any);\n unbindAllRuleHooks(engine);\n bindRuleHooks(engine, this.ruleService, rules, ctx.logger as any);\n } else {\n ctx.logger.warn('SharingServicePlugin: engine has no hook API — sharing rule auto-evaluation disabled');\n }\n } catch (err: any) {\n ctx.logger.warn('SharingServicePlugin: sharing-rule subsystem not started', { error: err?.message });\n }\n }\n\n // ── Share-Link service (capability tokens) ────────────────\n //\n // Registered alongside the principal-based sharing service so\n // both surfaces resolve through the same kernel. The HTTP\n // endpoints are optional — services that just want programmatic\n // access can set `registerShareLinkRoutes: false` and call the\n // service via `ctx.getService('shareLinks')`.\n try {\n this.linkService = new ShareLinkService({ engine: engine as SharingEngine });\n ctx.registerService('shareLinks', this.linkService);\n\n if (this.options.registerShareLinkRoutes !== false) {\n let http: IHttpServer | null = null;\n try {\n http = ctx.getService<IHttpServer>('http-server');\n } catch {\n // No HTTP server — service still reachable via getService.\n }\n if (http) {\n registerShareLinkRoutes(http, this.linkService, engine as SharingEngine, {\n basePath: this.options.shareLinkBasePath,\n });\n ctx.logger.info(\n 'SharingServicePlugin: share-link routes mounted at ' +\n (this.options.shareLinkBasePath ?? '/api/v1/share-links'),\n );\n } else {\n ctx.logger.warn(\n 'SharingServicePlugin: no HTTP server — share-link REST routes not registered. ' +\n 'ShareLinkService is still reachable via kernel.getService(\"shareLinks\").',\n );\n }\n }\n } catch (err: any) {\n ctx.logger.warn('SharingServicePlugin: share-link subsystem not started', { error: err?.message });\n }\n });\n }\n}\n\n/**\n * Build the engine middleware that injects read filters and gates\n * write operations. Exported so it can be unit-tested without booting\n * a kernel.\n */\nexport function buildSharingMiddleware(service: SharingService): EngineMiddleware {\n return async function sharingMiddleware(ctx: OperationContext, next: () => Promise<void>) {\n const op = ctx.operation;\n const exec = ctx.context as any;\n\n // READS — AND the visibility filter into the AST.\n if (op === 'find' || op === 'findOne' || op === 'count' || op === 'aggregate') {\n const filter = await service.buildReadFilter(ctx.object, exec ?? {});\n if (filter) {\n const ast: any = ctx.ast ?? {};\n ast.where = composeAnd(ast.where, filter);\n ast.filter = composeAnd(ast.filter, filter);\n ctx.ast = ast;\n }\n return next();\n }\n\n // WRITES — gate on canEdit for update / delete.\n if (op === 'update' || op === 'delete') {\n const data: any = ctx.data;\n const options: any = ctx.options;\n const id = inferTargetId(data, options);\n if (id != null) {\n const ok = await service.canEdit(ctx.object, String(id), exec ?? {});\n if (!ok) {\n const err: any = new Error(\n `FORBIDDEN: insufficient privileges to ${op} ${ctx.object} ${id}`,\n );\n err.code = 'FORBIDDEN';\n err.status = 403;\n throw err;\n }\n }\n return next();\n }\n\n // INSERT / others pass through — ownership stamping is the\n // application's job (and is enforced by existing field defaults).\n return next();\n };\n}\n\nfunction composeAnd(existing: unknown, addition: unknown): unknown {\n if (existing == null) return addition;\n if (addition == null) return existing;\n // Both objects — merge with $and.\n if (\n typeof existing === 'object' && existing !== null && !Array.isArray(existing) &&\n typeof addition === 'object' && addition !== null && !Array.isArray(addition)\n ) {\n const ex: any = existing;\n if (Array.isArray(ex.$and)) {\n return { $and: [...ex.$and, addition] };\n }\n // Heuristic: if existing has no operator keys, attempt shallow merge;\n // otherwise nest into $and to preserve semantics.\n return { $and: [existing, addition] };\n }\n return { $and: [existing, addition] };\n}\n\nfunction inferTargetId(data: any, options: any): string | number | undefined {\n if (data && typeof data === 'object' && data.id != null) return data.id;\n if (options && typeof options === 'object') {\n if (options.id != null) return options.id;\n if (options.where && typeof options.where === 'object' && options.where.id != null) {\n return options.where.id;\n }\n if (options.filter && typeof options.filter === 'object' && options.filter.id != null) {\n return options.filter.id;\n }\n }\n return undefined;\n}\n"],"mappings":"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","names":["import_data","import_data","import_identity","row","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SharingTranslations"]}
1
+ {"version":3,"sources":["../src/translations/en.objects.generated.ts","../src/translations/zh-CN.objects.generated.ts","../src/translations/ja-JP.objects.generated.ts","../src/translations/es-ES.objects.generated.ts","../src/translations/index.ts","../src/index.ts","../src/objects/sys-record-share.object.ts","../src/objects/sys-sharing-rule.object.ts","../src/objects/sys-share-link.object.ts","../src/sharing-service.ts","../src/team-graph.ts","../src/role-graph.ts","../src/department-graph.ts","../src/sharing-rule-service.ts","../src/share-link-service.ts","../src/share-link-routes.ts","../src/rule-hooks.ts","../src/sharing-plugin.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'en'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const enObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"Record Share\",\n pluralLabel: \"Record Shares\",\n description: \"Per-record sharing grant — extends OWD with explicit access\",\n fields: {\n id: {\n label: \"Share ID\"\n },\n object_name: {\n label: \"Object\",\n help: \"Short object name of the shared record\"\n },\n record_id: {\n label: \"Record\",\n help: \"Primary key of the shared record within object_name\"\n },\n recipient_type: {\n label: \"Recipient Type\",\n help: \"Kind of principal that holds the grant\",\n options: {\n user: \"user\",\n group: \"group\",\n role: \"role\",\n role_and_subordinates: \"role_and_subordinates\",\n guest: \"guest\"\n }\n },\n recipient_id: {\n label: \"Recipient\",\n help: \"ID of the user/group/role that receives access\"\n },\n access_level: {\n label: \"Access Level\",\n help: \"What the recipient can do — read | edit | full (transfer/share/delete)\",\n options: {\n read: \"read\",\n edit: \"edit\",\n full: \"full\"\n }\n },\n source: {\n label: \"Source\",\n help: \"Why this grant exists — used by the rule evaluator to reconcile\",\n options: {\n manual: \"manual\",\n rule: \"rule\",\n team: \"team\",\n inherited: \"inherited\"\n }\n },\n source_id: {\n label: \"Source ID\",\n help: \"Rule name / team id when source != manual\"\n },\n granted_by: {\n label: \"Granted By\",\n help: \"User that created the grant (manual only)\"\n },\n reason: {\n label: \"Reason\",\n help: \"Optional free-text explanation surfaced to the recipient\"\n },\n created_at: {\n label: \"Created At\"\n },\n updated_at: {\n label: \"Updated At\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"Granted to Me\"\n },\n granted_by_me: {\n label: \"Granted by Me\"\n },\n by_object: {\n label: \"By Object\"\n },\n manual_grants: {\n label: \"Manual Grants\"\n },\n rule_grants: {\n label: \"Rule Grants\"\n },\n all_shares: {\n label: \"All\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"Sharing Rule\",\n pluralLabel: \"Sharing Rules\",\n description: \"Declarative sharing rule that auto-materialises sys_record_share grants. Authored via defineSharingRule() in code or the Studio criteria builder.\",\n fields: {\n id: {\n label: \"Rule ID\"\n },\n organization_id: {\n label: \"Organization\",\n help: \"Tenant that owns this rule; null = global\"\n },\n name: {\n label: \"Name\",\n help: \"Unique snake_case rule name\"\n },\n label: {\n label: \"Display Label\"\n },\n description: {\n label: \"Description\"\n },\n object_name: {\n label: \"Object\",\n help: \"Short object name (e.g. opportunity, account)\"\n },\n criteria_json: {\n label: \"Criteria (FilterCondition JSON)\",\n help: \"JSON FilterCondition matched against records of object_name. Empty = match all.\"\n },\n recipient_type: {\n label: \"Recipient Type\",\n help: \"Kind of principal that receives access — expanded to user grants at evaluation time. `department` walks the parent_department_id tree; `team` is flat (better-auth).\",\n options: {\n user: \"user\",\n team: \"team\",\n department: \"department\",\n role: \"role\",\n queue: \"queue\"\n }\n },\n recipient_id: {\n label: \"Recipient\",\n help: \"department id / team id / role name / queue name / user id depending on recipient_type\"\n },\n access_level: {\n label: \"Access Level\",\n options: {\n read: \"read\",\n edit: \"edit\",\n full: \"full\"\n }\n },\n active: {\n label: \"Active\",\n help: \"Only active rules participate in lifecycle evaluation\"\n },\n created_at: {\n label: \"Created At\"\n },\n updated_at: {\n label: \"Updated At\"\n }\n },\n _views: {\n active: {\n label: \"Active\"\n },\n inactive: {\n label: \"Inactive\"\n },\n by_object: {\n label: \"By Object\"\n },\n all_rules: {\n label: \"All\"\n }\n }\n },\n sys_share_link: {\n label: \"Share Link\",\n pluralLabel: \"Share Links\",\n description: \"Opaque capability token granting access to a single record. Notion/Figma-style public link sharing.\",\n fields: {\n id: {\n label: \"Link ID\"\n },\n token: {\n label: \"Token\",\n help: \"Opaque URL-safe random token (≥ 22 chars). The only secret in this row.\"\n },\n object_name: {\n label: \"Object\",\n help: \"Short object name of the shared record (e.g. ai_conversation, contracts_contract)\"\n },\n record_id: {\n label: \"Record\",\n help: \"Primary key of the shared record within object_name\"\n },\n permission: {\n label: \"Permission\",\n help: \"What the link holder can do with the record\",\n options: {\n view: \"View\",\n comment: \"Comment\",\n edit: \"Edit\"\n }\n },\n audience: {\n label: \"Audience\",\n help: \"Gating layer applied on top of the token check\",\n options: {\n public: \"Public (indexable)\",\n link_only: \"Anyone with the link\",\n signed_in: \"Signed-in users\",\n email: \"Specific emails\"\n }\n },\n expires_at: {\n label: \"Expires At\",\n help: \"When set, resolveToken returns null after this timestamp\"\n },\n email_allowlist: {\n label: \"Email Allowlist\",\n help: \"Lowercased addresses checked when audience=email\"\n },\n password_hash: {\n label: \"Password Hash\",\n help: \"Argon2/bcrypt hash. When set, the UI prompts for a password before rendering.\"\n },\n redact_fields: {\n label: \"Per-Link Redactions\",\n help: \"Extra fields stripped from the response, on top of the object-default set\"\n },\n label: {\n label: \"Label\",\n help: \"Free-text shown in the share dialog (e.g. \\\"ACME Q3 contract\\\")\"\n },\n revoked_at: {\n label: \"Revoked At\",\n help: \"When set, the link is permanently disabled\"\n },\n created_by: {\n label: \"Created By\",\n help: \"Issuer of the link\"\n },\n created_at: {\n label: \"Created At\"\n },\n last_used_at: {\n label: \"Last Used At\",\n help: \"Stamped by resolveToken; used by the dashboard to highlight active links\"\n },\n use_count: {\n label: \"Use Count\",\n help: \"Incremented by resolveToken on every successful resolution\"\n }\n },\n _views: {\n active_links: {\n label: \"Active\"\n },\n by_me: {\n label: \"Created by Me\"\n },\n revoked: {\n label: \"Revoked\"\n },\n all_links: {\n label: \"All\"\n }\n }\n }\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'zh-CN'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const zhCNObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"记录共享\",\n pluralLabel: \"记录共享\",\n description: \"按记录粒度的共享授权——在 OWD 基础上提供显式访问\",\n fields: {\n id: {\n label: \"共享 ID\"\n },\n object_name: {\n label: \"对象\",\n help: \"被共享记录的短对象名\"\n },\n record_id: {\n label: \"记录\",\n help: \"object_name 对应对象内该共享记录的主键\"\n },\n recipient_type: {\n label: \"接收方类型\",\n help: \"持有该授权的主体类型\",\n options: {\n user: \"用户\",\n group: \"组\",\n role: \"角色\",\n role_and_subordinates: \"角色及下级\",\n guest: \"访客\"\n }\n },\n recipient_id: {\n label: \"接收方\",\n help: \"获得访问权限的用户 / 组 / 角色 ID\"\n },\n access_level: {\n label: \"访问级别\",\n help: \"接收方可以执行的操作——read | edit | full(转移 / 共享 / 删除)\",\n options: {\n read: \"读取\",\n edit: \"编辑\",\n full: \"完全访问\"\n }\n },\n source: {\n label: \"来源\",\n help: \"该授权存在的原因——供规则求值器对账使用\",\n options: {\n manual: \"手动\",\n rule: \"规则\",\n team: \"团队\",\n inherited: \"继承\"\n }\n },\n source_id: {\n label: \"来源 ID\",\n help: \"当 source != manual 时,对应规则名 / 团队 ID\"\n },\n granted_by: {\n label: \"授权人\",\n help: \"创建该授权的用户(仅手动授权)\"\n },\n reason: {\n label: \"原因\",\n help: \"可选的自由文本说明,会展示给接收方\"\n },\n created_at: {\n label: \"创建时间\"\n },\n updated_at: {\n label: \"更新时间\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"授予我的\"\n },\n granted_by_me: {\n label: \"我授予的\"\n },\n by_object: {\n label: \"按对象\"\n },\n manual_grants: {\n label: \"手动授权\"\n },\n rule_grants: {\n label: \"规则授权\"\n },\n all_shares: {\n label: \"全部\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"共享规则\",\n pluralLabel: \"共享规则\",\n description: \"声明式共享规则,会自动生成 sys_record_share 授权。可在代码中通过 defineSharingRule() 编写,或在 Studio 条件构建器中维护。\",\n fields: {\n id: {\n label: \"规则 ID\"\n },\n organization_id: {\n label: \"组织\",\n help: \"拥有该规则的租户;null = 全局\"\n },\n name: {\n label: \"名称\",\n help: \"唯一的 snake_case 规则名称\"\n },\n label: {\n label: \"显示标签\"\n },\n description: {\n label: \"描述\"\n },\n object_name: {\n label: \"对象\",\n help: \"短对象名(例如 opportunity、account)\"\n },\n criteria_json: {\n label: \"条件(FilterCondition JSON)\",\n help: \"针对 object_name 记录匹配的 JSON FilterCondition。为空表示匹配全部。\"\n },\n recipient_type: {\n label: \"接收方类型\",\n help: \"接收访问权限的主体类型——求值时会展开为用户授权。`department` 会沿 parent_department_id 树展开;`team` 为扁平结构(better-auth)。\",\n options: {\n user: \"用户\",\n team: \"团队\",\n department: \"部门\",\n role: \"角色\",\n queue: \"队列\"\n }\n },\n recipient_id: {\n label: \"接收方\",\n help: \"根据 recipient_type 填写 department id / team id / role name / queue name / user id\"\n },\n access_level: {\n label: \"访问级别\",\n options: {\n read: \"读取\",\n edit: \"编辑\",\n full: \"完全访问\"\n }\n },\n active: {\n label: \"启用\",\n help: \"只有启用的规则才会参与生命周期求值\"\n },\n created_at: {\n label: \"创建时间\"\n },\n updated_at: {\n label: \"更新时间\"\n }\n },\n _views: {\n active: {\n label: \"启用\"\n },\n inactive: {\n label: \"停用\"\n },\n by_object: {\n label: \"按对象\"\n },\n all_rules: {\n label: \"全部\"\n }\n }\n },\n sys_share_link: {\n label: \"共享链接\",\n pluralLabel: \"共享链接\",\n description: \"授予对单条记录访问权限的不透明能力令牌。类似 Notion/Figma 的公开链接共享。\",\n fields: {\n id: {\n label: \"链接 ID\"\n },\n token: {\n label: \"令牌\",\n help: \"URL 安全的不透明随机令牌(≥ 22 个字符)。本记录中唯一的机密信息。\"\n },\n object_name: {\n label: \"对象\",\n help: \"所共享记录的对象短名称(例如 ai_conversation、contracts_contract)\"\n },\n record_id: {\n label: \"记录\",\n help: \"object_name 内所共享记录的主键\"\n },\n permission: {\n label: \"权限\",\n help: \"链接持有者可对该记录执行的操作\",\n options: {\n view: \"查看\",\n comment: \"评论\",\n edit: \"编辑\"\n }\n },\n audience: {\n label: \"受众\",\n help: \"在令牌校验之上额外施加的访问限制层\",\n options: {\n public: \"公开(可被索引)\",\n link_only: \"任何持有链接的人\",\n signed_in: \"已登录用户\",\n email: \"指定邮箱\"\n }\n },\n expires_at: {\n label: \"过期时间\",\n help: \"设置后,超过此时间点 resolveToken 将返回 null\"\n },\n email_allowlist: {\n label: \"邮箱白名单\",\n help: \"当 audience=email 时校验的小写邮箱地址\"\n },\n password_hash: {\n label: \"密码哈希\",\n help: \"Argon2/bcrypt 哈希值。设置后,界面会在呈现内容前提示输入密码。\"\n },\n redact_fields: {\n label: \"按链接脱敏字段\",\n help: \"在对象默认脱敏集之上,从响应中额外剔除的字段\"\n },\n label: {\n label: \"标签\",\n help: \"在共享对话框中显示的自由文本(例如 \\\"ACME Q3 合同\\\")\"\n },\n revoked_at: {\n label: \"撤销时间\",\n help: \"设置后,该链接将被永久停用\"\n },\n created_by: {\n label: \"创建人\",\n help: \"链接的签发者\"\n },\n created_at: {\n label: \"创建时间\"\n },\n last_used_at: {\n label: \"最近使用时间\",\n help: \"由 resolveToken 标记;仪表盘据此高亮显示活跃链接\"\n },\n use_count: {\n label: \"使用次数\",\n help: \"每次成功解析时由 resolveToken 递增\"\n }\n },\n _views: {\n active_links: {\n label: \"活跃\"\n },\n by_me: {\n label: \"我创建的\"\n },\n revoked: {\n label: \"已撤销\"\n },\n all_links: {\n label: \"全部\"\n }\n }\n }\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'ja-JP'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const jaJPObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"レコード共有\",\n pluralLabel: \"レコード共有\",\n description: \"レコードごとの共有付与 — OWD に明示的なアクセスを追加\",\n fields: {\n id: {\n label: \"共有 ID\"\n },\n object_name: {\n label: \"オブジェクト\",\n help: \"共有レコードの短いオブジェクト名\"\n },\n record_id: {\n label: \"レコード\",\n help: \"object_name 内の共有レコードの主キー\"\n },\n recipient_type: {\n label: \"受信者タイプ\",\n help: \"付与を保持するプリンシパルの種別\",\n options: {\n user: \"ユーザー\",\n group: \"グループ\",\n role: \"ロール\",\n role_and_subordinates: \"ロールと下位階層\",\n guest: \"ゲスト\"\n }\n },\n recipient_id: {\n label: \"受信者\",\n help: \"アクセスを受け取るユーザー/グループ/ロールの ID\"\n },\n access_level: {\n label: \"アクセスレベル\",\n help: \"受信者に許可される操作 — read | edit | full(転送/共有/削除)\",\n options: {\n read: \"閲覧\",\n edit: \"編集\",\n full: \"フルアクセス\"\n }\n },\n source: {\n label: \"ソース\",\n help: \"この付与が存在する理由 — ルール評価者が調整に使用\",\n options: {\n manual: \"手動\",\n rule: \"ルール\",\n team: \"チーム\",\n inherited: \"継承\"\n }\n },\n source_id: {\n label: \"ソース ID\",\n help: \"source != manual の場合のルール名 / チーム ID\"\n },\n granted_by: {\n label: \"付与者\",\n help: \"付与を作成したユーザー(手動のみ)\"\n },\n reason: {\n label: \"理由\",\n help: \"受信者に表示されるオプションの自由記述説明\"\n },\n created_at: {\n label: \"作成日時\"\n },\n updated_at: {\n label: \"更新日時\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"自分への付与\"\n },\n granted_by_me: {\n label: \"自分による付与\"\n },\n by_object: {\n label: \"オブジェクト別\"\n },\n manual_grants: {\n label: \"手動付与\"\n },\n rule_grants: {\n label: \"ルール付与\"\n },\n all_shares: {\n label: \"すべて\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"共有ルール\",\n pluralLabel: \"共有ルール\",\n description: \"sys_record_share 付与を自動マテリアライズする宣言的共有ルール。コードの defineSharingRule() または Studio の条件ビルダーで作成します。\",\n fields: {\n id: {\n label: \"ルール ID\"\n },\n organization_id: {\n label: \"組織\",\n help: \"このルールを所有するテナント。null = グローバル\"\n },\n name: {\n label: \"名前\",\n help: \"一意の snake_case ルール名\"\n },\n label: {\n label: \"表示名\"\n },\n description: {\n label: \"説明\"\n },\n object_name: {\n label: \"オブジェクト\",\n help: \"短いオブジェクト名(例: opportunity、account)\"\n },\n criteria_json: {\n label: \"条件(FilterCondition JSON)\",\n help: \"object_name のレコードに対してマッチする JSON FilterCondition。空 = すべてにマッチ。\"\n },\n recipient_type: {\n label: \"受信者タイプ\",\n help: \"アクセスを受け取るプリンシパルの種別 — 評価時にユーザー付与に展開されます。`department` は parent_department_id ツリーをたどります。`team` はフラット(better-auth)。\",\n options: {\n user: \"ユーザー\",\n team: \"チーム\",\n department: \"部門\",\n role: \"ロール\",\n queue: \"キュー\"\n }\n },\n recipient_id: {\n label: \"受信者\",\n help: \"recipient_type に応じた部門 ID / チーム ID / ロール名 / キュー名 / ユーザー ID\"\n },\n access_level: {\n label: \"アクセスレベル\",\n options: {\n read: \"閲覧\",\n edit: \"編集\",\n full: \"フルアクセス\"\n }\n },\n active: {\n label: \"有効\",\n help: \"有効なルールのみがライフサイクル評価に参加します\"\n },\n created_at: {\n label: \"作成日時\"\n },\n updated_at: {\n label: \"更新日時\"\n }\n },\n _views: {\n active: {\n label: \"有効\"\n },\n inactive: {\n label: \"無効\"\n },\n by_object: {\n label: \"オブジェクト別\"\n },\n all_rules: {\n label: \"すべて\"\n }\n }\n },\n sys_share_link: {\n label: \"共有リンク\",\n pluralLabel: \"共有リンク\",\n description: \"単一レコードへのアクセスを許可する不透明なケーパビリティトークン。Notion / Figma スタイルの公開リンク共有。\",\n fields: {\n id: {\n label: \"リンク ID\"\n },\n token: {\n label: \"トークン\",\n help: \"URL セーフな不透明ランダムトークン(22 文字以上)。この行で唯一の機密情報です。\"\n },\n object_name: {\n label: \"オブジェクト\",\n help: \"共有対象レコードのオブジェクト短縮名(例: ai_conversation、contracts_contract)\"\n },\n record_id: {\n label: \"レコード\",\n help: \"object_name 内における共有対象レコードの主キー\"\n },\n permission: {\n label: \"権限\",\n help: \"リンク保持者がレコードに対して実行できる操作\",\n options: {\n view: \"閲覧\",\n comment: \"コメント\",\n edit: \"編集\"\n }\n },\n audience: {\n label: \"対象者\",\n help: \"トークン検証の上に適用されるアクセス制御レイヤー\",\n options: {\n public: \"公開(インデックス可能)\",\n link_only: \"リンクを知っている全員\",\n signed_in: \"サインイン済みユーザー\",\n email: \"特定のメールアドレス\"\n }\n },\n expires_at: {\n label: \"有効期限\",\n help: \"設定すると、このタイムスタンプ以降は resolveToken が null を返します\"\n },\n email_allowlist: {\n label: \"メール許可リスト\",\n help: \"audience=email のときに照合される小文字のメールアドレス\"\n },\n password_hash: {\n label: \"パスワードハッシュ\",\n help: \"Argon2/bcrypt ハッシュ。設定すると、表示前に UI がパスワードの入力を求めます。\"\n },\n redact_fields: {\n label: \"リンク単位のマスキング\",\n help: \"オブジェクト既定のマスキング集合に加えて、レスポンスから除外する追加フィールド\"\n },\n label: {\n label: \"ラベル\",\n help: \"共有ダイアログに表示される自由記述テキスト(例: \\\"ACME Q3 contract\\\")\"\n },\n revoked_at: {\n label: \"失効日時\",\n help: \"設定すると、リンクは恒久的に無効化されます\"\n },\n created_by: {\n label: \"作成者\",\n help: \"リンクの発行者\"\n },\n created_at: {\n label: \"作成日時\"\n },\n last_used_at: {\n label: \"最終使用日時\",\n help: \"resolveToken によって記録されます。ダッシュボードでアクティブなリンクを強調表示するために使用されます\"\n },\n use_count: {\n label: \"使用回数\",\n help: \"解決が成功するたびに resolveToken によって加算されます\"\n }\n },\n _views: {\n active_links: {\n label: \"アクティブ\"\n },\n by_me: {\n label: \"自分が作成\"\n },\n revoked: {\n label: \"失効済み\"\n },\n all_links: {\n label: \"すべて\"\n }\n }\n }\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Auto-generated by 'os i18n extract' for locale 'es-ES'.\n * Edit translations in place; re-run extract (with --merge) to fill new gaps.\n * Do not hand-edit the structure — only the leaf string values.\n */\n\nimport type { TranslationData } from '@objectstack/spec/system';\n\nexport const esESObjects: NonNullable<TranslationData['objects']> = {\n sys_record_share: {\n label: \"Compartición de registro\",\n pluralLabel: \"Comparticiones de registro\",\n description: \"Concesión de compartición por registro; amplía OWD con acceso explícito.\",\n fields: {\n id: {\n label: \"ID de compartición\"\n },\n object_name: {\n label: \"Objeto\",\n help: \"Nombre corto del objeto del registro compartido.\"\n },\n record_id: {\n label: \"Registro\",\n help: \"Clave primaria del registro compartido dentro de object_name.\"\n },\n recipient_type: {\n label: \"Tipo de destinatario\",\n help: \"Tipo de principal que posee la concesión.\",\n options: {\n user: \"Usuario\",\n group: \"Grupo\",\n role: \"Rol\",\n role_and_subordinates: \"Rol y subordinados\",\n guest: \"Invitado\"\n }\n },\n recipient_id: {\n label: \"Destinatario\",\n help: \"ID del usuario/grupo/rol que recibe acceso.\"\n },\n access_level: {\n label: \"Nivel de acceso\",\n help: \"Lo que puede hacer el destinatario: read | edit | full (transfer/share/delete).\",\n options: {\n read: \"Leer\",\n edit: \"Editar\",\n full: \"Total\"\n }\n },\n source: {\n label: \"Origen\",\n help: \"Motivo por el que existe esta concesión; lo utiliza el evaluador de reglas para reconciliar.\",\n options: {\n manual: \"Manual\",\n rule: \"Regla\",\n team: \"Equipo\",\n inherited: \"Heredado\"\n }\n },\n source_id: {\n label: \"ID de origen\",\n help: \"Nombre de la regla / ID del equipo cuando source != manual.\"\n },\n granted_by: {\n label: \"Concedido por\",\n help: \"Usuario que creó la concesión (solo manual).\"\n },\n reason: {\n label: \"Motivo\",\n help: \"Explicación opcional en texto libre que se muestra al destinatario.\"\n },\n created_at: {\n label: \"Creado el\"\n },\n updated_at: {\n label: \"Actualizado el\"\n }\n },\n _views: {\n granted_to_me: {\n label: \"Concedidos a mí\"\n },\n granted_by_me: {\n label: \"Concedidos por mí\"\n },\n by_object: {\n label: \"Por objeto\"\n },\n manual_grants: {\n label: \"Concesiones manuales\"\n },\n rule_grants: {\n label: \"Concesiones por regla\"\n },\n all_shares: {\n label: \"Todas\"\n }\n }\n },\n sys_sharing_rule: {\n label: \"Regla de compartición\",\n pluralLabel: \"Reglas de compartición\",\n description: \"Regla de compartición declarativa que materializa automáticamente concesiones de sys_record_share. Se define mediante defineSharingRule() en código o con el generador de criterios de Studio.\",\n fields: {\n id: {\n label: \"ID de regla\"\n },\n organization_id: {\n label: \"Organización\",\n help: \"Tenant que posee esta regla; null = global.\"\n },\n name: {\n label: \"Nombre\",\n help: \"Nombre de regla snake_case único.\"\n },\n label: {\n label: \"Nombre visible\"\n },\n description: {\n label: \"Descripción\"\n },\n object_name: {\n label: \"Objeto\",\n help: \"Nombre corto del objeto (p. ej. opportunity, account).\"\n },\n criteria_json: {\n label: \"Criterios (JSON de FilterCondition)\",\n help: \"FilterCondition JSON comparado con los registros de object_name. Vacío = coincide con todos.\"\n },\n recipient_type: {\n label: \"Tipo de destinatario\",\n help: \"Tipo de principal que recibe acceso; se expande a concesiones de usuario durante la evaluación. `department` recorre el árbol parent_department_id; `team` es plano (better-auth).\",\n options: {\n user: \"Usuario\",\n team: \"Equipo\",\n department: \"Departamento\",\n role: \"Rol\",\n queue: \"Cola\"\n }\n },\n recipient_id: {\n label: \"Destinatario\",\n help: \"ID de departamento / ID de equipo / nombre del rol / nombre de la cola / ID del usuario según recipient_type.\"\n },\n access_level: {\n label: \"Nivel de acceso\",\n options: {\n read: \"Leer\",\n edit: \"Editar\",\n full: \"Total\"\n }\n },\n active: {\n label: \"Activo\",\n help: \"Solo las reglas activas participan en la evaluación del ciclo de vida.\"\n },\n created_at: {\n label: \"Creado el\"\n },\n updated_at: {\n label: \"Actualizado el\"\n }\n },\n _views: {\n active: {\n label: \"Activo\"\n },\n inactive: {\n label: \"Inactivo\"\n },\n by_object: {\n label: \"Por objeto\"\n },\n all_rules: {\n label: \"Todas\"\n }\n }\n },\n sys_share_link: {\n label: \"Enlace de uso compartido\",\n pluralLabel: \"Enlaces de uso compartido\",\n description: \"Token de capacidad opaco que concede acceso a un único registro. Uso compartido mediante enlace público al estilo de Notion/Figma.\",\n fields: {\n id: {\n label: \"ID del enlace\"\n },\n token: {\n label: \"Token\",\n help: \"Token aleatorio opaco seguro para URL (≥ 22 caracteres). El único secreto de esta fila.\"\n },\n object_name: {\n label: \"Objeto\",\n help: \"Nombre corto del objeto del registro compartido (p. ej. ai_conversation, contracts_contract)\"\n },\n record_id: {\n label: \"Registro\",\n help: \"Clave principal del registro compartido dentro de object_name\"\n },\n permission: {\n label: \"Permiso\",\n help: \"Lo que el titular del enlace puede hacer con el registro\",\n options: {\n view: \"Ver\",\n comment: \"Comentar\",\n edit: \"Editar\"\n }\n },\n audience: {\n label: \"Audiencia\",\n help: \"Capa de control aplicada por encima de la verificación del token\",\n options: {\n public: \"Público (indexable)\",\n link_only: \"Cualquier persona con el enlace\",\n signed_in: \"Usuarios con sesión iniciada\",\n email: \"Correos específicos\"\n }\n },\n expires_at: {\n label: \"Caduca el\",\n help: \"Cuando se establece, resolveToken devuelve null después de esta marca de tiempo\"\n },\n email_allowlist: {\n label: \"Lista de correos permitidos\",\n help: \"Direcciones en minúsculas que se comprueban cuando audience=email\"\n },\n password_hash: {\n label: \"Hash de contraseña\",\n help: \"Hash Argon2/bcrypt. Cuando se establece, la interfaz solicita una contraseña antes de mostrar el contenido.\"\n },\n redact_fields: {\n label: \"Campos ocultos por enlace\",\n help: \"Campos adicionales que se eliminan de la respuesta, además del conjunto predeterminado del objeto\"\n },\n label: {\n label: \"Etiqueta\",\n help: \"Texto libre que se muestra en el cuadro de diálogo de uso compartido (p. ej. \\\"ACME Q3 contract\\\")\"\n },\n revoked_at: {\n label: \"Revocado el\",\n help: \"Cuando se establece, el enlace queda deshabilitado permanentemente\"\n },\n created_by: {\n label: \"Creado por\",\n help: \"Emisor del enlace\"\n },\n created_at: {\n label: \"Creado el\"\n },\n last_used_at: {\n label: \"Último uso el\",\n help: \"Lo registra resolveToken; el panel lo usa para resaltar los enlaces activos\"\n },\n use_count: {\n label: \"Número de usos\",\n help: \"Lo incrementa resolveToken en cada resolución correcta\"\n }\n },\n _views: {\n active_links: {\n label: \"Activos\"\n },\n by_me: {\n label: \"Creados por mí\"\n },\n revoked: {\n label: \"Revocados\"\n },\n all_links: {\n label: \"Todos\"\n }\n }\n }\n};\n","// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * SharingTranslations — i18n bundle owned by this plugin (ADR-0029 D8).\n *\n * Object label/field/view/action translations for the sys_* objects this\n * plugin owns. Loaded at runtime via the plugin's `kernel:ready` hook\n * (`i18n.loadTranslations`). Regenerate with `os i18n extract` against\n * `scripts/i18n-extract.config.ts`.\n */\n\nimport type { TranslationBundle } from '@objectstack/spec/system';\nimport { enObjects } from './en.objects.generated.js';\nimport { zhCNObjects } from './zh-CN.objects.generated.js';\nimport { jaJPObjects } from './ja-JP.objects.generated.js';\nimport { esESObjects } from './es-ES.objects.generated.js';\n\nexport const SharingTranslations: TranslationBundle = {\n en: { objects: enObjects },\n 'zh-CN': { objects: zhCNObjects },\n 'ja-JP': { objects: jaJPObjects },\n 'es-ES': { objects: esESObjects },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * @objectstack/plugin-sharing\n *\n * Record-level sharing for ObjectStack. Implements `ISharingService`\n * and installs an engine middleware that enforces\n * `object.sharingModel` (`private` / `read`) against the\n * authenticated execution context.\n */\n\nexport { SysRecordShare, SysSharingRule, SysShareLink } from './objects/index.js';\nexport { SysDepartment, SysDepartmentMember } from '@objectstack/platform-objects/identity';\nexport {\n SharingService,\n type SharingEngine,\n type SharingServiceOptions,\n} from './sharing-service.js';\nexport {\n SharingRuleService,\n type SharingRuleServiceOptions,\n} from './sharing-rule-service.js';\nexport {\n ShareLinkService,\n type ShareLinkServiceOptions,\n} from './share-link-service.js';\nexport {\n registerShareLinkRoutes,\n type ShareLinkRoutesOptions,\n} from './share-link-routes.js';\nexport { TeamGraphService, expandPrincipal, type TeamGraphOptions } from './team-graph.js';\nexport { DepartmentGraphService, type DepartmentGraphOptions } from './department-graph.js';\nexport { bindRuleHooks, unbindAllRuleHooks, SHARING_RULE_HOOK_PACKAGE } from './rule-hooks.js';\nexport {\n SharingServicePlugin,\n buildSharingMiddleware,\n type SharingPluginOptions,\n} from './sharing-plugin.js';\nexport type {\n ISharingService,\n ISharingRuleService,\n ITeamGraphService,\n IDepartmentGraphService,\n RecordShare,\n GrantShareInput,\n SharingExecutionContext,\n ShareAccessLevel,\n ShareRecipientType,\n ShareSource,\n SharingRuleRow,\n DefineSharingRuleInput,\n SharingRuleEvaluationResult,\n SharingRuleRecipientType,\n IShareLinkService,\n ShareLink,\n CreateShareLinkInput,\n ListShareLinksFilter,\n ResolveShareLinkResult,\n ShareLinkExecutionContext,\n ShareLinkPermission,\n ShareLinkAudience,\n} from '@objectstack/spec/contracts';\nexport { SHARE_LINK_SERVICE } from '@objectstack/spec/contracts';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_record_share — Per-Record Sharing Grant\n *\n * Bridges the ownership-only baseline established by `object.sharingModel`\n * with the real-world need to delegate access to a single record. Each\n * row says: \"principal P has access level L on (object O, record R),\n * because of source S (manual grant or rule).\"\n *\n * Enforcement lives in `@objectstack/plugin-sharing`:\n * - For objects with `sharingModel: 'private'`, the engine middleware\n * AND-s `{$or:[{owner_id:userId},{id:{$in:[grantedRecordIds]}}]}`\n * into every `find` against that object.\n * - For objects with `sharingModel: 'private' | 'read'`, the same\n * middleware enforces edit/delete by checking ownership OR a share\n * row with `access_level in ('edit','full')`.\n *\n * Conventions:\n * - `object_name` is the short object name (e.g. `account`, `lead`).\n * - `recipient_type` mirrors `ShareRecipientType` from the spec\n * (`user` is enforced today; `group`/`role` are persisted for\n * forward-compatibility).\n * - `source = 'manual'` rows are created by a user via the REST\n * `POST /data/:object/:id/shares` endpoint. `source = 'rule'` rows\n * are materialised by the sharing-rule evaluator (future); the\n * `source_id` lets the evaluator reconcile stale grants.\n *\n * @namespace sys\n */\nexport const SysRecordShare = ObjectSchema.create({\n name: 'sys_record_share',\n label: 'Record Share',\n pluralLabel: 'Record Shares',\n icon: 'share',\n isSystem: true,\n managedBy: 'system',\n description: 'Per-record sharing grant — extends OWD with explicit access',\n titleFormat: '{object_name}/{record_id} → {recipient_id} ({access_level})',\n compactLayout: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source'],\n\n listViews: {\n granted_to_me: {\n type: 'grid',\n name: 'granted_to_me',\n label: 'Granted to Me',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'access_level', 'source', 'granted_by', 'created_at'],\n filter: [\n { field: 'recipient_type', operator: 'equals', value: 'user' },\n { field: 'recipient_id', operator: 'equals', value: '{current_user_id}' },\n ],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n granted_by_me: {\n type: 'grid',\n name: 'granted_by_me',\n label: 'Granted by Me',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source', 'created_at'],\n filter: [\n { field: 'granted_by', operator: 'equals', value: '{current_user_id}' },\n ],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n by_object: {\n type: 'grid',\n name: 'by_object',\n label: 'By Object',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source', 'created_at'],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'created_at', order: 'desc' }],\n grouping: { fields: [{ field: 'object_name', order: 'asc', collapsed: false }] },\n pagination: { pageSize: 100 },\n },\n manual_grants: {\n type: 'grid',\n name: 'manual_grants',\n label: 'Manual Grants',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'granted_by', 'reason', 'created_at'],\n filter: [{ field: 'source', operator: 'equals', value: 'manual' }],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n rule_grants: {\n type: 'grid',\n name: 'rule_grants',\n label: 'Rule Grants',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_id', 'access_level', 'source_id', 'created_at'],\n filter: [{ field: 'source', operator: 'in', value: ['rule', 'team', 'inherited'] }],\n sort: [{ field: 'source_id', order: 'asc' }, { field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n all_shares: {\n type: 'grid',\n name: 'all_shares',\n label: 'All',\n data: { provider: 'object', object: 'sys_record_share' },\n columns: ['object_name', 'record_id', 'recipient_type', 'recipient_id', 'access_level', 'source', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 100 },\n },\n },\n\n fields: {\n id: Field.text({\n label: 'Share ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n // ── Target (which record is being shared) ────────────────────\n object_name: Field.text({\n label: 'Object',\n required: true,\n maxLength: 100,\n description: 'Short object name of the shared record',\n group: 'Target',\n }),\n\n record_id: Field.text({\n label: 'Record',\n required: true,\n maxLength: 100,\n description: 'Primary key of the shared record within object_name',\n group: 'Target',\n }),\n\n // ── Recipient (who receives access) ──────────────────────────\n recipient_type: Field.select(\n ['user', 'group', 'role', 'role_and_subordinates', 'guest'],\n {\n label: 'Recipient Type',\n required: true,\n defaultValue: 'user',\n description: 'Kind of principal that holds the grant',\n group: 'Recipient',\n },\n ),\n\n recipient_id: Field.text({\n label: 'Recipient',\n required: true,\n maxLength: 100,\n description: 'ID of the user/group/role that receives access',\n group: 'Recipient',\n }),\n\n access_level: Field.select(\n ['read', 'edit', 'full'],\n {\n label: 'Access Level',\n required: true,\n defaultValue: 'read',\n description: 'What the recipient can do — read | edit | full (transfer/share/delete)',\n group: 'Recipient',\n },\n ),\n\n // ── Provenance ───────────────────────────────────────────────\n source: Field.select(\n ['manual', 'rule', 'team', 'inherited'],\n {\n label: 'Source',\n required: true,\n defaultValue: 'manual',\n description: 'Why this grant exists — used by the rule evaluator to reconcile',\n group: 'Provenance',\n },\n ),\n\n source_id: Field.text({\n label: 'Source ID',\n required: false,\n maxLength: 200,\n description: 'Rule name / team id when source != manual',\n group: 'Provenance',\n }),\n\n granted_by: Field.lookup('sys_user', {\n label: 'Granted By',\n required: false,\n description: 'User that created the grant (manual only)',\n group: 'Provenance',\n }),\n\n reason: Field.text({\n label: 'Reason',\n required: false,\n maxLength: 500,\n description: 'Optional free-text explanation surfaced to the recipient',\n group: 'Provenance',\n }),\n\n // ── Lifecycle ────────────────────────────────────────────────\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n required: false,\n group: 'System',\n }),\n },\n\n indexes: [\n // Hot path: \"all records visible to user U on object O\" — the\n // middleware reads (object_name, recipient_type, recipient_id) to\n // build the `id IN (...)` predicate on every find.\n { fields: ['object_name', 'recipient_type', 'recipient_id'] },\n // \"all grants on this record\" — used by the share-management UI\n // and by canEdit() to look up explicit grants.\n { fields: ['object_name', 'record_id'] },\n // Reconciliation key for rule-driven shares.\n { fields: ['source', 'source_id'] },\n ],\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_sharing_rule — Declarative record-sharing rule.\n *\n * Salesforce-style criteria-based sharing: \"any record on object O that\n * matches criteria C is granted access level A to recipient R\". Rules\n * are evaluated by `@objectstack/plugin-sharing` and materialise their\n * grants as rows in `sys_record_share` with `source='rule'` and\n * `source_id={rule.id}` so the evaluator can reconcile (delete + re-\n * insert) on rule updates without touching manual grants.\n *\n * Evaluation triggers:\n * - `afterInsert` / `afterUpdate` on the target object (per-record,\n * incremental — the hot path).\n * - REST `POST /sharing/rules/:id/evaluate` (admin-initiated\n * bulk reconcile — used after rule edits).\n *\n * Criteria are stored as JSON (a normal `FilterCondition`) so the\n * existing engine `find()` can do the matching natively. v1 supports\n * simple `{field, op, value}` style filters; CEL predicates are a\n * follow-up.\n *\n * @namespace sys\n */\nexport const SysSharingRule = ObjectSchema.create({\n name: 'sys_sharing_rule',\n label: 'Sharing Rule',\n pluralLabel: 'Sharing Rules',\n icon: 'shield-check',\n isSystem: true,\n managedBy: 'config',\n // Sharing rules can now be authored visually via the Studio criteria\n // builder (apps/studio/src/components/SharingCriteriaBuilder.tsx).\n // We still recommend `defineSharingRule({...})` for repo-controlled\n // baselines, but admins can safely create/edit/delete from the UI.\n userActions: { create: true, edit: true, delete: true, import: false },\n description: 'Declarative sharing rule that auto-materialises sys_record_share grants. Authored via defineSharingRule() in code or the Studio criteria builder.',\n displayNameField: 'name',\n titleFormat: '{label}',\n compactLayout: ['name', 'object_name', 'recipient_type', 'recipient_id', 'access_level', 'active'],\n\n listViews: {\n active: {\n type: 'grid',\n name: 'active',\n label: 'Active',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['label', 'object_name', 'recipient_type', 'recipient_id', 'access_level', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: true }],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n inactive: {\n type: 'grid',\n name: 'inactive',\n label: 'Inactive',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['label', 'object_name', 'recipient_type', 'recipient_id', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: false }],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n by_object: {\n type: 'grid',\n name: 'by_object',\n label: 'By Object',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['object_name', 'label', 'recipient_type', 'access_level', 'active'],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'label', order: 'asc' }],\n grouping: { fields: [{ field: 'object_name', order: 'asc', collapsed: false }] },\n pagination: { pageSize: 100 },\n },\n all_rules: {\n type: 'grid',\n name: 'all_rules',\n label: 'All',\n data: { provider: 'object', object: 'sys_sharing_rule' },\n columns: ['label', 'object_name', 'recipient_type', 'recipient_id', 'access_level', 'active', 'updated_at'],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n },\n\n fields: {\n id: Field.text({ label: 'Rule ID', required: true, readonly: true, group: 'System' }),\n\n organization_id: Field.lookup('sys_organization', {\n label: 'Organization',\n required: false,\n group: 'System',\n description: 'Tenant that owns this rule; null = global',\n }),\n\n name: Field.text({\n label: 'Name',\n required: true,\n maxLength: 100,\n description: 'Unique snake_case rule name',\n group: 'Identity',\n }),\n\n label: Field.text({\n label: 'Display Label',\n required: true,\n maxLength: 200,\n group: 'Identity',\n }),\n\n description: Field.textarea({\n label: 'Description',\n required: false,\n group: 'Identity',\n }),\n\n object_name: Field.text({\n label: 'Object',\n required: true,\n maxLength: 100,\n description: 'Short object name (e.g. opportunity, account)',\n group: 'Target',\n }),\n\n criteria_json: Field.textarea({\n label: 'Criteria (FilterCondition JSON)',\n required: false,\n description: 'JSON FilterCondition matched against records of object_name. Empty = match all.',\n group: 'Target',\n }),\n\n recipient_type: Field.select(\n ['user', 'team', 'department', 'role', 'role_and_subordinates', 'queue'],\n {\n label: 'Recipient Type',\n required: true,\n defaultValue: 'department',\n description: 'Kind of principal that receives access — expanded to user grants at evaluation time. `department` walks the parent_department_id tree; `team` is flat (better-auth); `role` is the role\\'s direct members; `role_and_subordinates` walks the sys_role.parent hierarchy to also include every subordinate role (ADR-0056 D6).',\n group: 'Recipient',\n },\n ),\n\n recipient_id: Field.text({\n label: 'Recipient',\n required: true,\n maxLength: 200,\n description: 'department id / team id / role name / queue name / user id depending on recipient_type',\n group: 'Recipient',\n }),\n\n access_level: Field.select(\n ['read', 'edit', 'full'],\n {\n label: 'Access Level',\n required: true,\n defaultValue: 'read',\n group: 'Recipient',\n },\n ),\n\n active: Field.boolean({\n label: 'Active',\n required: false,\n defaultValue: true,\n description: 'Only active rules participate in lifecycle evaluation',\n group: 'Lifecycle',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n required: false,\n group: 'System',\n }),\n },\n\n indexes: [\n { fields: ['object_name', 'active'] },\n { fields: ['name'], unique: true },\n { fields: ['organization_id'] },\n ],\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_share_link — Capability-Token Public Share Links\n *\n * Each row authorises read (or write) access to ONE record of ONE\n * object via an opaque URL-safe token. Complements `sys_record_share`,\n * which models principal-based grants (share with a specific user /\n * team / role). A single record may have rows in both tables; the\n * union determines effective access.\n *\n * Lifecycle:\n *\n * 1. `IShareLinkService.createLink` validates the request against the\n * target object's `publicSharing` whitelist and inserts a row.\n * Token is a 24-char URL-safe random string.\n *\n * 2. `IShareLinkService.resolveToken` (called from the public\n * `/api/v1/share-links/:token` middleware on every request)\n * verifies the row is not revoked / not expired, applies audience\n * / password gates, increments `use_count` + `last_used_at`, and\n * returns the effective redaction set.\n *\n * 3. `IShareLinkService.revokeLink` stamps `revoked_at`. Rows are\n * preserved for audit; resolveToken returns null after revocation.\n *\n * Conventions:\n * - `object_name` is the short object name (`account`, `ai_conversation`, …)\n * - `record_id` is the primary key of the target record within object_name\n * - `audience` mirrors `ShareLinkAudience` in spec/contracts; the\n * middleware enforces additional gating per audience\n * - `redact_fields` overlays on top of the schema-default redaction\n * set declared on `object.publicSharing.redactFields`\n *\n * managedBy: 'system' — admins inspect via the audit grid but all\n * writes flow through `IShareLinkService` so the per-object opt-in,\n * expiry caps, and audit hooks fire.\n *\n * @namespace sys\n */\nexport const SysShareLink = ObjectSchema.create({\n name: 'sys_share_link',\n label: 'Share Link',\n pluralLabel: 'Share Links',\n icon: 'link-2',\n isSystem: true,\n managedBy: 'system',\n description: 'Opaque capability token granting access to a single record. Notion/Figma-style public link sharing.',\n titleFormat: '{object_name}/{record_id} ({permission})',\n compactLayout: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'revoked_at'],\n\n listViews: {\n active_links: {\n type: 'grid',\n name: 'active_links',\n label: 'Active',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'use_count', 'last_used_at'],\n filter: [{ field: 'revoked_at', operator: 'isNull' }],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 100 },\n },\n by_me: {\n type: 'grid',\n name: 'by_me',\n label: 'Created by Me',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'revoked_at'],\n filter: [{ field: 'created_by', operator: 'equals', value: '{current_user_id}' }],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 100 },\n },\n revoked: {\n type: 'grid',\n name: 'revoked',\n label: 'Revoked',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'revoked_at', 'created_by'],\n filter: [{ field: 'revoked_at', operator: 'isNotNull' }],\n sort: [{ field: 'revoked_at', order: 'desc' }],\n pagination: { pageSize: 50 },\n },\n all_links: {\n type: 'grid',\n name: 'all_links',\n label: 'All',\n data: { provider: 'object', object: 'sys_share_link' },\n columns: ['object_name', 'record_id', 'permission', 'audience', 'expires_at', 'revoked_at', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n pagination: { pageSize: 200 },\n },\n },\n\n fields: {\n id: Field.text({\n label: 'Link ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n // ── Token (the secret) ───────────────────────────────────────\n token: Field.text({\n label: 'Token',\n required: true,\n maxLength: 64,\n description: 'Opaque URL-safe random token (≥ 22 chars). The only secret in this row.',\n group: 'Token',\n }),\n\n // ── Target ───────────────────────────────────────────────────\n object_name: Field.text({\n label: 'Object',\n required: true,\n maxLength: 100,\n description: 'Short object name of the shared record (e.g. ai_conversation, contracts_contract)',\n group: 'Target',\n }),\n\n record_id: Field.text({\n label: 'Record',\n required: true,\n maxLength: 100,\n description: 'Primary key of the shared record within object_name',\n group: 'Target',\n }),\n\n // ── Access Policy ────────────────────────────────────────────\n permission: Field.select(\n [\n { label: 'View', value: 'view' },\n { label: 'Comment', value: 'comment' },\n { label: 'Edit', value: 'edit' },\n ],\n {\n label: 'Permission',\n required: true,\n defaultValue: 'view',\n description: 'What the link holder can do with the record',\n group: 'Access Policy',\n },\n ),\n\n audience: Field.select(\n [\n { label: 'Public (indexable)', value: 'public' },\n { label: 'Anyone with the link', value: 'link_only' },\n { label: 'Signed-in users', value: 'signed_in' },\n { label: 'Specific emails', value: 'email' },\n ],\n {\n label: 'Audience',\n required: true,\n defaultValue: 'link_only',\n description: 'Gating layer applied on top of the token check',\n group: 'Access Policy',\n },\n ),\n\n expires_at: Field.datetime({\n label: 'Expires At',\n description: 'When set, resolveToken returns null after this timestamp',\n group: 'Access Policy',\n }),\n\n email_allowlist: Field.json({\n label: 'Email Allowlist',\n description: 'Lowercased addresses checked when audience=email',\n group: 'Access Policy',\n }),\n\n password_hash: Field.text({\n label: 'Password Hash',\n maxLength: 256,\n description: 'Argon2/bcrypt hash. When set, the UI prompts for a password before rendering.',\n group: 'Access Policy',\n }),\n\n redact_fields: Field.json({\n label: 'Per-Link Redactions',\n description: 'Extra fields stripped from the response, on top of the object-default set',\n group: 'Access Policy',\n }),\n\n label: Field.text({\n label: 'Label',\n maxLength: 200,\n description: 'Free-text shown in the share dialog (e.g. \"ACME Q3 contract\")',\n group: 'Metadata',\n }),\n\n // ── Lifecycle ────────────────────────────────────────────────\n revoked_at: Field.datetime({\n label: 'Revoked At',\n readonly: true,\n description: 'When set, the link is permanently disabled',\n group: 'Lifecycle',\n }),\n\n created_by: Field.lookup('sys_user', {\n label: 'Created By',\n readonly: true,\n description: 'Issuer of the link',\n group: 'Lifecycle',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'Lifecycle',\n }),\n\n last_used_at: Field.datetime({\n label: 'Last Used At',\n readonly: true,\n description: 'Stamped by resolveToken; used by the dashboard to highlight active links',\n group: 'Lifecycle',\n }),\n\n use_count: Field.number({\n label: 'Use Count',\n defaultValue: 0,\n readonly: true,\n description: 'Incremented by resolveToken on every successful resolution',\n group: 'Lifecycle',\n }),\n },\n\n indexes: [\n // Hot path: resolveToken — one row lookup per public request.\n { fields: ['token'], unique: true },\n // Management UI: \"all links for this record\".\n { fields: ['object_name', 'record_id'] },\n // \"Active links I issued\".\n { fields: ['created_by', 'revoked_at'] },\n // Reaper for expired rows (background sweep).\n { fields: ['expires_at'] },\n ],\n\n enable: {\n trackHistory: false,\n searchable: false,\n apiEnabled: true,\n // The /api/v1/share-links endpoints are the authoritative surface;\n // the generic data API is exposed read-only for the admin grid.\n apiMethods: ['get', 'list'],\n trash: false,\n mru: false,\n clone: false,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n ISharingService,\n RecordShare,\n GrantShareInput,\n SharingExecutionContext,\n ShareAccessLevel,\n} from '@objectstack/spec/contracts';\n\n/**\n * Shape of the data engine the service actually needs. Kept narrow so\n * unit tests can pass an in-memory fake without depending on the full\n * ObjectQL engine class.\n */\nexport interface SharingEngine {\n find(object: string, options?: any): Promise<any[]>;\n findOne?(object: string, options?: any): Promise<any>;\n insert(object: string, data: any, options?: any): Promise<any>;\n update(object: string, idOrData: any, dataOrOptions?: any, options?: any): Promise<any>;\n delete(object: string, options?: any): Promise<any>;\n getSchema?(object: string): any | undefined;\n}\n\n/**\n * Random share id. Keeps the plugin self-contained (no `crypto.randomUUID`\n * dependency in environments that don't expose it on `globalThis`).\n */\nfunction makeShareId(): string {\n const g: any = globalThis as any;\n if (g.crypto?.randomUUID) return `shr_${g.crypto.randomUUID()}`;\n return `shr_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** System-elevated context for the plugin's own queries / mutations. */\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\n/**\n * Owner field convention. Hard-coded to `owner_id` for MVP — the\n * sharing model in Salesforce / ServiceNow / Dynamics all assume a\n * single owner field, and customising it is a follow-up. Objects\n * without `owner_id` are treated as \"unowned\" and read filters are\n * suppressed (they fall back to OWD-public behaviour).\n */\nconst OWNER_FIELD = 'owner_id';\n\n/**\n * Effective sharing model — collapses the authorable OWD vocabulary onto the\n * three behaviours this service enforces (ADR-0056 D1):\n * - `private` → owner-only read + write\n * - `public_read` / legacy `read` → everyone reads, owner writes\n * - everything else → public (no record-level filter)\n *\n * \"Everything else\" covers the canonical `public_read_write`, the legacy\n * `read_write` / `full` aliases, `controlled_by_parent` (scoped separately by\n * the security plugin), and objects that declare no `sharingModel` at all — so\n * existing behaviour is preserved until an admin opts an object in.\n */\nfunction effectiveSharingModel(schema: any): 'private' | 'read' | 'public' {\n const m = schema?.sharingModel ?? schema?.security?.sharingModel;\n if (m === 'private') return 'private';\n if (m === 'read' || m === 'public_read') return 'read';\n return 'public';\n}\n\nfunction hasOwnerField(schema: any): boolean {\n return Boolean(schema?.fields && OWNER_FIELD in schema.fields);\n}\n\nexport interface SharingServiceOptions {\n engine: SharingEngine;\n /** Object names that bypass sharing — typically platform internals. */\n bypassObjects?: string[];\n}\n\n/**\n * Default `ISharingService` implementation.\n *\n * Stores every grant in `sys_record_share`. The plugin layer registers\n * an engine middleware that calls `buildReadFilter` / `canEdit` so that\n * neither this class nor its callers need to know about middleware\n * plumbing.\n */\nexport class SharingService implements ISharingService {\n private readonly engine: SharingEngine;\n private readonly bypassObjects: Set<string>;\n\n constructor(options: SharingServiceOptions) {\n this.engine = options.engine;\n this.bypassObjects = new Set([\n 'sys_record_share',\n 'sys_user',\n 'sys_organization',\n 'sys_member',\n 'sys_role',\n 'sys_permission_set',\n 'sys_user_permission_set',\n 'sys_role_permission_set',\n ...(options.bypassObjects ?? []),\n ]);\n }\n\n /**\n * Build a `FilterCondition` restricting `find` to records the caller\n * may see. Returns `null` when no filter should be applied.\n */\n async buildReadFilter(\n object: string,\n context: SharingExecutionContext,\n ): Promise<unknown | null> {\n if (this.shouldBypass(object, context)) return null;\n\n const schema = this.engine.getSchema?.(object);\n if (!schema) return null;\n if (effectiveSharingModel(schema) !== 'private') return null;\n if (!hasOwnerField(schema)) return null;\n if (!context.userId) {\n // Authenticated context with no user id is a degenerate case\n // (e.g. anonymous API key). Restrict to nothing rather than\n // accidentally leaking owner-only data.\n return { id: '__deny_all__' };\n }\n\n const grants = await this.engine.find('sys_record_share', {\n filter: {\n object_name: object,\n recipient_type: 'user',\n recipient_id: context.userId,\n },\n fields: ['record_id', 'access_level'],\n limit: 5000,\n context: SYSTEM_CTX,\n });\n\n const grantedIds: string[] = Array.isArray(grants)\n ? grants.map((g: any) => String(g.record_id)).filter(Boolean)\n : [];\n\n if (grantedIds.length === 0) {\n return { [OWNER_FIELD]: context.userId };\n }\n\n return {\n $or: [\n { [OWNER_FIELD]: context.userId },\n { id: { $in: grantedIds } },\n ],\n };\n }\n\n /**\n * Return `true` if the caller may edit `(object, recordId)`. Always\n * `true` for system context, public objects, and objects without an\n * owner field.\n */\n async canEdit(\n object: string,\n recordId: string,\n context: SharingExecutionContext,\n ): Promise<boolean> {\n if (this.shouldBypass(object, context)) return true;\n\n const schema = this.engine.getSchema?.(object);\n if (!schema) return true;\n const model = effectiveSharingModel(schema);\n if (model === 'public') return true;\n if (!hasOwnerField(schema)) return true;\n if (!context.userId) return false;\n\n // 1) Ownership — fast path.\n const own = await this.engine.find(object, {\n filter: { id: recordId },\n fields: ['id', OWNER_FIELD],\n limit: 1,\n context: SYSTEM_CTX,\n });\n const owner = Array.isArray(own) && own[0] ? (own[0] as any)[OWNER_FIELD] : undefined;\n if (owner && String(owner) === String(context.userId)) return true;\n\n // 2) Explicit edit / full share.\n const editGrants = await this.engine.find('sys_record_share', {\n filter: {\n object_name: object,\n record_id: recordId,\n recipient_type: 'user',\n recipient_id: context.userId,\n access_level: { $in: ['edit', 'full'] },\n },\n fields: ['id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n return Array.isArray(editGrants) && editGrants.length > 0;\n }\n\n /**\n * Upsert a share row. Returning the existing row when an identical\n * grant already exists keeps the REST endpoint idempotent.\n */\n async grant(\n input: GrantShareInput,\n context: SharingExecutionContext,\n ): Promise<RecordShare> {\n if (!input.object) throw new Error('VALIDATION_FAILED: object is required');\n if (!input.recordId) throw new Error('VALIDATION_FAILED: recordId is required');\n if (!input.recipientId) throw new Error('VALIDATION_FAILED: recipientId is required');\n\n const recipientType = input.recipientType ?? 'user';\n const accessLevel: ShareAccessLevel = input.accessLevel ?? 'read';\n const source = input.source ?? 'manual';\n\n // Upsert: if a row with same (object, record, recipient) exists,\n // update its access level / reason; otherwise insert a new one.\n const existing = await this.engine.find('sys_record_share', {\n filter: {\n object_name: input.object,\n record_id: input.recordId,\n recipient_type: recipientType,\n recipient_id: input.recipientId,\n },\n limit: 1,\n context: SYSTEM_CTX,\n });\n const now = new Date().toISOString();\n if (Array.isArray(existing) && existing[0]) {\n const row: any = existing[0];\n const patch: any = {\n id: row.id,\n access_level: accessLevel,\n source,\n source_id: input.sourceId ?? row.source_id ?? null,\n reason: input.reason ?? row.reason ?? null,\n updated_at: now,\n };\n await this.engine.update('sys_record_share', patch, { context: SYSTEM_CTX });\n return { ...row, ...patch } as RecordShare;\n }\n\n const id = makeShareId();\n const row: any = {\n id,\n object_name: input.object,\n record_id: input.recordId,\n recipient_type: recipientType,\n recipient_id: input.recipientId,\n access_level: accessLevel,\n source,\n source_id: input.sourceId ?? null,\n granted_by: context.userId ?? null,\n reason: input.reason ?? null,\n created_at: now,\n updated_at: now,\n };\n await this.engine.insert('sys_record_share', row, { context: SYSTEM_CTX });\n return row as RecordShare;\n }\n\n /** Delete a share row by id. No-op when not found. */\n async revoke(shareId: string, _context: SharingExecutionContext): Promise<void> {\n if (!shareId) throw new Error('VALIDATION_FAILED: shareId is required');\n await this.engine.delete('sys_record_share', {\n where: { id: shareId },\n context: SYSTEM_CTX,\n });\n }\n\n /** List share rows for `(object, recordId)`. */\n async listShares(\n object: string,\n recordId: string,\n _context: SharingExecutionContext,\n ): Promise<RecordShare[]> {\n const rows = await this.engine.find('sys_record_share', {\n filter: { object_name: object, record_id: recordId },\n orderBy: [{ field: 'created_at', order: 'desc' }],\n limit: 500,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) ? (rows as RecordShare[]) : [];\n }\n\n // ── helpers ──────────────────────────────────────────────────────\n\n private shouldBypass(object: string, context: SharingExecutionContext): boolean {\n if (context?.isSystem) return true;\n if (this.bypassObjects.has(object)) return true;\n return false;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { ITeamGraphService } from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\ntype Cache = {\n expandUsers?: Map<string, string[]>;\n expandRole?: Map<string, string[]>;\n manager?: Map<string, string | null>;\n};\n\nexport interface TeamGraphOptions {\n engine: SharingEngine;\n /** Optional tenant scope; null means cross-tenant lookups. */\n organizationId?: string | null;\n /** Optional shared cache across one evaluator pass. */\n cache?: Cache;\n}\n\n/**\n * Default {@link ITeamGraphService} implementation backed by\n * `sys_team` + `sys_team_member` (better-auth's flat collaboration\n * grouping) plus `sys_member.role` for tenant role expansion.\n *\n * **This service does NOT walk a hierarchy.** Teams here are flat —\n * the enterprise org chart lives in `sys_department` and is served by\n * {@link DepartmentGraphService}.\n *\n * All queries elevate to {@link SYSTEM_CTX} since the graph is platform\n * metadata; callers (sharing rule evaluator, approval engine) own their\n * own enforcement.\n */\nexport class TeamGraphService implements ITeamGraphService {\n private readonly engine: SharingEngine;\n private readonly organizationId: string | null;\n private readonly cache: Cache;\n\n constructor(opts: TeamGraphOptions) {\n this.engine = opts.engine;\n this.organizationId = opts.organizationId ?? null;\n this.cache = opts.cache ?? {};\n this.cache.expandUsers ??= new Map();\n this.cache.expandRole ??= new Map();\n this.cache.manager ??= new Map();\n }\n\n async expandUsers(teamId: string): Promise<string[]> {\n if (!teamId) return [];\n const cached = this.cache.expandUsers!.get(teamId);\n if (cached) return cached;\n\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_team_member', {\n filter: { team_id: teamId },\n fields: ['user_id'],\n limit: 10000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n const users = Array.from(new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)));\n this.cache.expandUsers!.set(teamId, users);\n return users;\n }\n\n async expandRoleUsers(roleName: string, organizationId?: string): Promise<string[]> {\n if (!roleName) return [];\n const key = `${organizationId ?? this.organizationId ?? '*'}::${roleName}`;\n const cached = this.cache.expandRole!.get(key);\n if (cached) return cached;\n const filter: Record<string, unknown> = { role: roleName };\n const org = organizationId ?? this.organizationId;\n if (org) filter.organization_id = org;\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_member', {\n filter,\n fields: ['user_id'],\n limit: 10000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n const users = Array.from(new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)));\n this.cache.expandRole!.set(key, users);\n return users;\n }\n\n async managerOf(userId: string, _organizationId?: string): Promise<string | null> {\n if (!userId) return null;\n if (this.cache.manager!.has(userId)) return this.cache.manager!.get(userId) ?? null;\n let row: any = null;\n try {\n const rows = await this.engine.find('sys_user', {\n filter: { id: userId },\n fields: ['id', 'manager_id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n row = Array.isArray(rows) ? rows[0] : null;\n } catch {\n row = null;\n }\n const mgr = row?.manager_id ? String(row.manager_id) : null;\n this.cache.manager!.set(userId, mgr);\n return mgr;\n }\n}\n\n/**\n * Convenience helper used by the sharing-rule evaluator + approval\n * engine: expand an approver / recipient descriptor of the form\n * `{type, value}` into a flat list of user IDs by routing to the\n * appropriate graph service.\n *\n * `team` → flat team members (this service).\n * `department` → recursive department members (delegated; requires a\n * {@link IDepartmentGraphService} instance passed in `opts.dept`).\n * `role` → tenant role members.\n * `manager` → submitter's manager via `record[value] ?? record.owner_id`.\n * `field` → literal user id stored in `record[value]`.\n * `user` → literal value.\n * Anything else echoes `type:value` for back-compat with legacy\n * substring-match approver flows.\n */\nexport async function expandPrincipal(\n input: { type: string; value: string; record?: any },\n ctx: { team: TeamGraphService; dept?: { expandUsers(id: string): Promise<string[]> }; organizationId?: string | null },\n): Promise<string[]> {\n const t = input.type;\n const v = String(input.value ?? '');\n if (!v) return [];\n if (t === 'user') return [v];\n if (t === 'team') return ctx.team.expandUsers(v);\n if (t === 'department' || t === 'dept') {\n if (ctx.dept) return ctx.dept.expandUsers(v);\n return [`${t}:${v}`];\n }\n if (t === 'role') return ctx.team.expandRoleUsers(v, ctx.organizationId ?? undefined);\n if (t === 'field' && input.record) {\n const fv = (input.record as any)[v];\n return fv ? [String(fv)] : [];\n }\n if (t === 'manager' && input.record) {\n const subject = (input.record as any)[v] ?? (input.record as any).owner_id;\n if (!subject) return [];\n const mgr = await ctx.team.managerOf(String(subject), ctx.organizationId ?? undefined);\n return mgr ? [mgr] : [];\n }\n // queue / unknown — fall back to raw prefix string so existing\n // string-match approver flows keep working.\n return [`${t}:${v}`];\n}\n","// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { SharingEngine } from './sharing-service.js';\nimport { TeamGraphService } from './team-graph.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\ntype RoleCache = {\n descendants?: Map<string, string[]>;\n expand?: Map<string, string[]>;\n};\n\nexport interface RoleGraphOptions {\n engine: SharingEngine;\n /** Optional tenant scope; null means cross-tenant lookups. */\n organizationId?: string | null;\n /** Optional shared cache across one evaluator pass. */\n cache?: RoleCache;\n /** Reused for role → direct-member-user expansion (sys_member.role). */\n teamGraph?: TeamGraphService;\n}\n\n/**\n * Role hierarchy graph (ADR-0056 D6).\n *\n * Walks `sys_role.parent` to resolve a role's SUBORDINATE roles, powering the\n * declarative `role_and_subordinates` sharing-rule recipient — Salesforce-style\n * \"grant access using the role hierarchy\", expressed per sharing rule rather\n * than hardcoded. A role's `parent` is its manager role, so the subordinates of\n * `R` are every role whose ancestor chain passes through `R`.\n *\n * All lookups elevate to a system context (the hierarchy is platform metadata);\n * callers own their own authorization. Cycles are guarded by a visited set.\n */\nexport class RoleGraphService {\n private readonly engine: SharingEngine;\n private readonly organizationId: string | null;\n private readonly cache: RoleCache;\n private readonly teamGraph: TeamGraphService;\n\n constructor(opts: RoleGraphOptions) {\n this.engine = opts.engine;\n this.organizationId = opts.organizationId ?? null;\n this.cache = opts.cache ?? {};\n this.cache.descendants ??= new Map();\n this.cache.expand ??= new Map();\n this.teamGraph =\n opts.teamGraph ?? new TeamGraphService({ engine: this.engine, organizationId: this.organizationId });\n }\n\n /** Direct child roles of `roleName` (`sys_role.parent === roleName`). */\n private async childRoles(roleName: string): Promise<string[]> {\n const filter: Record<string, unknown> = { parent: roleName };\n if (this.organizationId) filter.organization_id = this.organizationId;\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_role', {\n filter,\n fields: ['name'],\n limit: 5000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n return Array.from(new Set((rows ?? []).map((r: any) => String(r.name ?? '')).filter(Boolean)));\n }\n\n /** `roleName` plus every role beneath it in the hierarchy (BFS, cycle-safe). */\n async descendantRoles(roleName: string): Promise<string[]> {\n if (!roleName) return [];\n const cached = this.cache.descendants!.get(roleName);\n if (cached) return cached;\n const out: string[] = [];\n const seen = new Set<string>();\n const queue: string[] = [roleName];\n while (queue.length) {\n const r = queue.shift()!;\n if (seen.has(r)) continue;\n seen.add(r);\n out.push(r);\n for (const child of await this.childRoles(r)) {\n if (!seen.has(child)) queue.push(child);\n }\n }\n this.cache.descendants!.set(roleName, out);\n return out;\n }\n\n /** Users holding `roleName` OR any subordinate role (the `role_and_subordinates` set). */\n async expandRoleAndSubordinates(roleName: string, organizationId?: string): Promise<string[]> {\n if (!roleName) return [];\n const org = organizationId ?? this.organizationId ?? '*';\n const key = `${org}::${roleName}`;\n const cached = this.cache.expand!.get(key);\n if (cached) return cached;\n const roles = await this.descendantRoles(roleName);\n const users = new Set<string>();\n for (const role of roles) {\n for (const uid of await this.teamGraph.expandRoleUsers(role, organizationId ?? this.organizationId ?? undefined)) {\n users.add(uid);\n }\n }\n const result = Array.from(users);\n this.cache.expand!.set(key, result);\n return result;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { IDepartmentGraphService } from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\nimport { TeamGraphService } from './team-graph.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\ntype DeptCache = {\n descendants?: Map<string, string[]>;\n expandUsers?: Map<string, string[]>;\n head?: Map<string, string | null>;\n};\n\nexport interface DepartmentGraphOptions {\n engine: SharingEngine;\n /** Optional tenant scope; null means cross-tenant lookups. */\n organizationId?: string | null;\n /** Optional shared cache across one evaluator pass. */\n cache?: DeptCache;\n /**\n * Optional team-graph instance to share role / manager lookups with —\n * department graph proxies `managerOf` through so callers only need one\n * service.\n */\n teamGraph?: TeamGraphService;\n}\n\n/**\n * Default {@link IDepartmentGraphService} implementation.\n *\n * Walks `sys_department.parent_department_id` for hierarchy and\n * `sys_department_member` for member expansion. Treats the optional\n * `active` flag as a hard filter (inactive departments contribute no\n * members and stop BFS descent into their subtrees).\n *\n * Reuses {@link TeamGraphService.managerOf} for user-level manager\n * lookup so callers can use this single service in approval / sharing\n * pipelines.\n */\nexport class DepartmentGraphService implements IDepartmentGraphService {\n private readonly engine: SharingEngine;\n private readonly organizationId: string | null;\n private readonly cache: DeptCache;\n private readonly teamGraph?: TeamGraphService;\n\n constructor(opts: DepartmentGraphOptions) {\n this.engine = opts.engine;\n this.organizationId = opts.organizationId ?? null;\n this.cache = opts.cache ?? {};\n this.cache.descendants ??= new Map();\n this.cache.expandUsers ??= new Map();\n this.cache.head ??= new Map();\n this.teamGraph = opts.teamGraph;\n }\n\n async descendants(departmentId: string): Promise<string[]> {\n if (!departmentId) return [];\n const cached = this.cache.descendants!.get(departmentId);\n if (cached) return cached;\n\n // Verify seed itself is active + within tenant scope.\n let seedActive = true;\n try {\n const seedRows = await this.engine.find('sys_department', {\n filter: this.orgScope({ id: departmentId }),\n fields: ['id', 'active'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n const seedRow: any = Array.isArray(seedRows) ? seedRows[0] : null;\n if (!seedRow) seedActive = false;\n else if (seedRow.active === false) seedActive = false;\n } catch {\n seedActive = false;\n }\n if (!seedActive) {\n this.cache.descendants!.set(departmentId, []);\n return [];\n }\n\n const seen = new Set<string>([departmentId]);\n const queue: string[] = [departmentId];\n while (queue.length) {\n const parent = queue.shift()!;\n let children: any[] = [];\n try {\n children = await this.engine.find('sys_department', {\n filter: this.orgScope({ parent_department_id: parent, active: { $ne: false } }),\n fields: ['id'],\n limit: 1000,\n context: SYSTEM_CTX,\n });\n } catch {\n children = [];\n }\n for (const c of children ?? []) {\n const cid = String((c as any).id ?? '');\n if (cid && !seen.has(cid)) {\n seen.add(cid);\n queue.push(cid);\n }\n }\n }\n const out = Array.from(seen);\n this.cache.descendants!.set(departmentId, out);\n return out;\n }\n\n async expandUsers(departmentId: string): Promise<string[]> {\n if (!departmentId) return [];\n const cached = this.cache.expandUsers!.get(departmentId);\n if (cached) return cached;\n\n const depts = await this.descendants(departmentId);\n if (depts.length === 0) return [];\n\n let rows: any[] = [];\n try {\n rows = await this.engine.find('sys_department_member', {\n filter: { department_id: { $in: depts } },\n fields: ['user_id'],\n limit: 10000,\n context: SYSTEM_CTX,\n });\n } catch {\n rows = [];\n }\n const users = Array.from(\n new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)),\n );\n this.cache.expandUsers!.set(departmentId, users);\n return users;\n }\n\n async headOf(departmentId: string): Promise<string | null> {\n if (!departmentId) return null;\n if (this.cache.head!.has(departmentId)) return this.cache.head!.get(departmentId) ?? null;\n let row: any = null;\n try {\n const rows = await this.engine.find('sys_department', {\n filter: { id: departmentId },\n fields: ['id', 'manager_user_id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n row = Array.isArray(rows) ? rows[0] : null;\n } catch {\n row = null;\n }\n const head = row?.manager_user_id ? String(row.manager_user_id) : null;\n this.cache.head!.set(departmentId, head);\n return head;\n }\n\n async managerOf(userId: string, organizationId?: string): Promise<string | null> {\n if (this.teamGraph) return this.teamGraph.managerOf(userId, organizationId);\n // Standalone fallback: read sys_user.manager_id directly.\n if (!userId) return null;\n try {\n const rows = await this.engine.find('sys_user', {\n filter: { id: userId },\n fields: ['id', 'manager_id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n const row: any = Array.isArray(rows) ? rows[0] : null;\n return row?.manager_id ? String(row.manager_id) : null;\n } catch {\n return null;\n }\n }\n\n private orgScope(filter: Record<string, unknown>): Record<string, unknown> {\n if (this.organizationId) return { ...filter, organization_id: this.organizationId };\n return filter;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n ISharingRuleService,\n DefineSharingRuleInput,\n SharingRuleRow,\n SharingRuleEvaluationResult,\n SharingExecutionContext,\n ShareAccessLevel,\n SharingRuleRecipientType,\n} from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\nimport type { SharingService } from './sharing-service.js';\nimport { TeamGraphService } from './team-graph.js';\nimport { RoleGraphService } from './role-graph.js';\nimport { DepartmentGraphService } from './department-graph.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\nfunction uid(prefix: string): string {\n const g: any = globalThis as any;\n if (g.crypto?.randomUUID) return `${prefix}_${g.crypto.randomUUID()}`;\n return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction parseCriteria(raw: unknown): unknown | undefined {\n if (raw == null || raw === '') return undefined;\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n if (!trimmed) return undefined;\n try {\n return JSON.parse(trimmed);\n } catch {\n // Treat unparsable strings as opaque — most likely a CEL source\n // that v1's evaluator doesn't grok yet; rule will match nothing.\n return undefined;\n }\n }\n return raw;\n}\n\nfunction rowFromRule(row: any): SharingRuleRow {\n return {\n id: row.id,\n organization_id: row.organization_id ?? null,\n name: row.name,\n label: row.label,\n description: row.description ?? null,\n object_name: row.object_name,\n criteria: parseCriteria(row.criteria_json),\n recipient_type: row.recipient_type as SharingRuleRecipientType,\n recipient_id: row.recipient_id,\n access_level: row.access_level as ShareAccessLevel,\n active: row.active !== false,\n created_at: row.created_at ?? undefined,\n updated_at: row.updated_at ?? undefined,\n };\n}\n\nexport interface SharingRuleServiceOptions {\n engine: SharingEngine;\n sharing: SharingService;\n logger?: { info?: Function; warn?: Function; error?: Function; debug?: Function };\n}\n\n/**\n * Default {@link ISharingRuleService} implementation.\n *\n * Stores rule definitions in `sys_sharing_rule` and materialises grants\n * as `sys_record_share` rows with `source='rule'` and `source_id={ruleId}`\n * so reconcile can diff old grants vs fresh evaluation results without\n * touching manual / team-derived shares.\n */\nexport class SharingRuleService implements ISharingRuleService {\n private readonly engine: SharingEngine;\n private readonly sharing: SharingService;\n private readonly logger?: SharingRuleServiceOptions['logger'];\n\n constructor(opts: SharingRuleServiceOptions) {\n this.engine = opts.engine;\n this.sharing = opts.sharing;\n this.logger = opts.logger;\n }\n\n async defineRule(input: DefineSharingRuleInput, context: SharingExecutionContext): Promise<SharingRuleRow> {\n if (!input.name) throw new Error('VALIDATION_FAILED: name is required');\n if (!input.label) throw new Error('VALIDATION_FAILED: label is required');\n if (!input.object) throw new Error('VALIDATION_FAILED: object is required');\n if (!input.recipientType) throw new Error('VALIDATION_FAILED: recipientType is required');\n if (!input.recipientId) throw new Error('VALIDATION_FAILED: recipientId is required');\n\n const orgId = (context as any)?.organizationId ?? (context as any)?.tenantId ?? null;\n const now = new Date().toISOString();\n const accessLevel: ShareAccessLevel = input.accessLevel ?? 'read';\n const active = input.active !== false;\n const criteriaJson = input.criteria == null\n ? null\n : (typeof input.criteria === 'string' ? input.criteria : JSON.stringify(input.criteria));\n\n const existing = await this.engine.find('sys_sharing_rule', {\n filter: orgId ? { name: input.name, organization_id: orgId } : { name: input.name },\n limit: 1,\n context: SYSTEM_CTX,\n });\n if (Array.isArray(existing) && existing[0]) {\n const row: any = existing[0];\n const patch: any = {\n id: row.id,\n label: input.label,\n description: input.description ?? null,\n object_name: input.object,\n criteria_json: criteriaJson,\n recipient_type: input.recipientType,\n recipient_id: input.recipientId,\n access_level: accessLevel,\n active,\n updated_at: now,\n };\n await this.engine.update('sys_sharing_rule', patch, { context: SYSTEM_CTX });\n return rowFromRule({ ...row, ...patch });\n }\n\n const newRow: any = {\n id: uid('srule'),\n organization_id: orgId,\n name: input.name,\n label: input.label,\n description: input.description ?? null,\n object_name: input.object,\n criteria_json: criteriaJson,\n recipient_type: input.recipientType,\n recipient_id: input.recipientId,\n access_level: accessLevel,\n active,\n created_at: now,\n updated_at: now,\n };\n await this.engine.insert('sys_sharing_rule', newRow, { context: SYSTEM_CTX });\n return rowFromRule(newRow);\n }\n\n async listRules(\n filter: { object?: string; activeOnly?: boolean },\n context: SharingExecutionContext,\n ): Promise<SharingRuleRow[]> {\n const where: any = {};\n if (filter.object) where.object_name = filter.object;\n if (filter.activeOnly) where.active = true;\n const orgId = (context as any)?.organizationId ?? (context as any)?.tenantId;\n if (orgId) where.organization_id = orgId;\n const rows = await this.engine.find('sys_sharing_rule', {\n filter: where,\n orderBy: [{ field: 'name', order: 'asc' }],\n limit: 1000,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) ? rows.map(rowFromRule) : [];\n }\n\n async getRule(idOrName: string, context: SharingExecutionContext): Promise<SharingRuleRow | null> {\n if (!idOrName) return null;\n const orgId = (context as any)?.organizationId ?? (context as any)?.tenantId;\n const byId = await this.engine.find('sys_sharing_rule', {\n filter: { id: idOrName },\n limit: 1,\n context: SYSTEM_CTX,\n });\n if (Array.isArray(byId) && byId[0]) return rowFromRule(byId[0]);\n const byName = await this.engine.find('sys_sharing_rule', {\n filter: orgId ? { name: idOrName, organization_id: orgId } : { name: idOrName },\n limit: 1,\n context: SYSTEM_CTX,\n });\n if (Array.isArray(byName) && byName[0]) return rowFromRule(byName[0]);\n return null;\n }\n\n async deleteRule(idOrName: string, context: SharingExecutionContext): Promise<void> {\n const row = await this.getRule(idOrName, context);\n if (!row) return;\n // Drop materialised grants first so we don't orphan them.\n await this.engine.delete('sys_record_share', {\n where: { source: 'rule', source_id: row.id },\n context: SYSTEM_CTX,\n } as any);\n await this.engine.delete('sys_sharing_rule', {\n where: { id: row.id },\n context: SYSTEM_CTX,\n } as any);\n }\n\n async evaluateRule(idOrName: string, context: SharingExecutionContext): Promise<SharingRuleEvaluationResult> {\n const rule = await this.getRule(idOrName, context);\n if (!rule) throw new Error('RULE_NOT_FOUND');\n if (!rule.active) {\n // Inactive — purge any leftover grants and report revoke count.\n const revoked = await this.purgeRuleGrants(rule.id);\n return { ruleId: rule.id, matchedRecords: 0, expandedUsers: 0, grantsCreated: 0, grantsUpdated: 0, grantsRevoked: revoked };\n }\n const matches = await this.findMatchingRecords(rule);\n const users = await this.expandRecipient(rule);\n return this.reconcile(rule, matches, users);\n }\n\n async evaluateAllForRecord(\n object: string,\n recordId: string,\n context: SharingExecutionContext,\n ): Promise<SharingRuleEvaluationResult[]> {\n const rules = await this.listRules({ object, activeOnly: true }, context);\n if (rules.length === 0) return [];\n const results: SharingRuleEvaluationResult[] = [];\n for (const rule of rules) {\n const match = await this.recordMatches(rule, recordId);\n const users = match ? await this.expandRecipient(rule) : [];\n results.push(await this.reconcileForRecord(rule, recordId, match, users));\n }\n return results;\n }\n\n // ── internals ─────────────────────────────────────────────────────\n\n private async findMatchingRecords(rule: SharingRuleRow): Promise<string[]> {\n const filter = (rule.criteria ?? {}) as any;\n try {\n const rows = await this.engine.find(rule.object_name, {\n filter,\n fields: ['id'],\n limit: 5000,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) ? rows.map((r: any) => String(r.id)).filter(Boolean) : [];\n } catch (err: any) {\n this.logger?.warn?.('[sharing-rule] criteria query failed', { rule: rule.name, error: err?.message });\n return [];\n }\n }\n\n private async recordMatches(rule: SharingRuleRow, recordId: string): Promise<boolean> {\n const filter = { ...((rule.criteria ?? {}) as any), id: recordId };\n try {\n const rows = await this.engine.find(rule.object_name, {\n filter,\n fields: ['id'],\n limit: 1,\n context: SYSTEM_CTX,\n });\n return Array.isArray(rows) && rows.length > 0;\n } catch {\n return false;\n }\n }\n\n private async expandRecipient(rule: SharingRuleRow): Promise<string[]> {\n const team = new TeamGraphService({\n engine: this.engine,\n organizationId: rule.organization_id ?? null,\n });\n if (rule.recipient_type === 'user') return [rule.recipient_id];\n if (rule.recipient_type === 'team') return team.expandUsers(rule.recipient_id);\n if (rule.recipient_type === 'department') {\n const dept = new DepartmentGraphService({\n engine: this.engine,\n organizationId: rule.organization_id ?? null,\n teamGraph: team,\n });\n return dept.expandUsers(rule.recipient_id);\n }\n if (rule.recipient_type === 'role') return team.expandRoleUsers(rule.recipient_id, rule.organization_id ?? undefined);\n if (rule.recipient_type === 'role_and_subordinates') {\n // ADR-0056 D6 — declarative role-hierarchy widening: this role + every\n // subordinate role's users (configured per sharing rule, not hardcoded).\n const roleGraph = new RoleGraphService({\n engine: this.engine,\n organizationId: rule.organization_id ?? null,\n teamGraph: team,\n });\n return roleGraph.expandRoleAndSubordinates(rule.recipient_id, rule.organization_id ?? undefined);\n }\n // queue — v1 stores literal; treat as no-op until queue impl lands.\n return [];\n }\n\n private async reconcile(\n rule: SharingRuleRow,\n matchedIds: string[],\n users: string[],\n ): Promise<SharingRuleEvaluationResult> {\n const existing = await this.engine.find('sys_record_share', {\n filter: { source: 'rule', source_id: rule.id },\n fields: ['id', 'record_id', 'recipient_id', 'access_level'],\n limit: 100000,\n context: SYSTEM_CTX,\n });\n const desired = new Map<string, { record_id: string; recipient_id: string }>();\n for (const rid of matchedIds) {\n for (const uId of users) desired.set(`${rid}::${uId}`, { record_id: rid, recipient_id: uId });\n }\n const existingMap = new Map<string, any>();\n for (const row of (existing ?? [])) existingMap.set(`${row.record_id}::${row.recipient_id}`, row);\n\n let created = 0;\n let updated = 0;\n let revoked = 0;\n\n // Upsert desired.\n for (const [k, want] of desired.entries()) {\n const cur = existingMap.get(k);\n if (cur) {\n if (cur.access_level !== rule.access_level) {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId: want.record_id,\n recipientType: 'user',\n recipientId: want.recipient_id,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n updated += 1;\n }\n existingMap.delete(k);\n } else {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId: want.record_id,\n recipientType: 'user',\n recipientId: want.recipient_id,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n created += 1;\n }\n }\n // Revoke stale.\n for (const [, stale] of existingMap.entries()) {\n await this.sharing.revoke(stale.id, SYSTEM_CTX as any);\n revoked += 1;\n }\n\n return {\n ruleId: rule.id,\n matchedRecords: matchedIds.length,\n expandedUsers: users.length,\n grantsCreated: created,\n grantsUpdated: updated,\n grantsRevoked: revoked,\n };\n }\n\n private async reconcileForRecord(\n rule: SharingRuleRow,\n recordId: string,\n match: boolean,\n users: string[],\n ): Promise<SharingRuleEvaluationResult> {\n const existing = await this.engine.find('sys_record_share', {\n filter: { source: 'rule', source_id: rule.id, record_id: recordId },\n fields: ['id', 'record_id', 'recipient_id', 'access_level'],\n limit: 1000,\n context: SYSTEM_CTX,\n });\n const existingMap = new Map<string, any>();\n for (const row of (existing ?? [])) existingMap.set(String(row.recipient_id), row);\n\n let created = 0;\n let updated = 0;\n let revoked = 0;\n\n if (match) {\n for (const userId of users) {\n const cur = existingMap.get(userId);\n if (cur) {\n if (cur.access_level !== rule.access_level) {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId,\n recipientType: 'user',\n recipientId: userId,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n updated += 1;\n }\n existingMap.delete(userId);\n } else {\n await this.sharing.grant(\n {\n object: rule.object_name,\n recordId,\n recipientType: 'user',\n recipientId: userId,\n accessLevel: rule.access_level,\n source: 'rule',\n sourceId: rule.id,\n reason: `rule:${rule.name}`,\n } as any,\n SYSTEM_CTX as any,\n );\n created += 1;\n }\n }\n }\n // Anything still in existingMap is stale (either match=false or\n // user no longer in expanded set).\n for (const [, stale] of existingMap.entries()) {\n await this.sharing.revoke(stale.id, SYSTEM_CTX as any);\n revoked += 1;\n }\n\n return {\n ruleId: rule.id,\n matchedRecords: match ? 1 : 0,\n expandedUsers: users.length,\n grantsCreated: created,\n grantsUpdated: updated,\n grantsRevoked: revoked,\n };\n }\n\n private async purgeRuleGrants(ruleId: string): Promise<number> {\n const existing = await this.engine.find('sys_record_share', {\n filter: { source: 'rule', source_id: ruleId },\n fields: ['id'],\n limit: 100000,\n context: SYSTEM_CTX,\n });\n let revoked = 0;\n for (const row of (existing ?? [])) {\n await this.sharing.revoke((row as any).id, SYSTEM_CTX as any);\n revoked += 1;\n }\n return revoked;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n IShareLinkService,\n ShareLink,\n CreateShareLinkInput,\n ListShareLinksFilter,\n ResolveShareLinkResult,\n ShareLinkExecutionContext,\n ShareLinkPermission,\n ShareLinkAudience,\n} from '@objectstack/spec/contracts';\nimport type { SharingEngine } from './sharing-service.js';\n\n/** Service-elevated context for the plugin's own queries / mutations. */\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\n/** URL-safe alphabet (RFC 4648 base64url minus padding). 64 symbols. */\nconst TOKEN_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n/** ~144 bits of entropy at 24 chars — well above the OWASP recommendation. */\nconst TOKEN_LENGTH = 24;\n\n/** Default value when no per-object cap is configured. */\nconst DEFAULT_MAX_EXPIRY_DAYS = 365;\n\n/**\n * Generate a URL-safe token. Uses `crypto.getRandomValues` when present\n * (browsers, Node ≥ 19) and falls back to `Math.random` only for the\n * pathological case of a polyfill-less old runtime. The fallback is\n * still ≥ 100 bits of entropy because of TOKEN_LENGTH.\n */\nfunction generateToken(length: number = TOKEN_LENGTH): string {\n const g: any = globalThis as any;\n const bytes = new Uint8Array(length);\n if (g.crypto?.getRandomValues) {\n g.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n let out = '';\n for (let i = 0; i < length; i++) {\n out += TOKEN_ALPHABET[bytes[i] % TOKEN_ALPHABET.length];\n }\n return out;\n}\n\n/** Internal helper — extract publicSharing policy from an object schema. */\nfunction getPolicy(schema: any): {\n enabled: boolean;\n allowedAudiences: ShareLinkAudience[];\n allowedPermissions: ShareLinkPermission[];\n maxExpiryDays?: number;\n redactFields: string[];\n} {\n const raw = schema?.publicSharing;\n if (!raw || raw.enabled !== true) {\n return {\n enabled: false,\n allowedAudiences: [],\n allowedPermissions: [],\n redactFields: [],\n };\n }\n return {\n enabled: true,\n allowedAudiences: (raw.allowedAudiences as ShareLinkAudience[] | undefined) ?? ['link_only'],\n allowedPermissions: (raw.allowedPermissions as ShareLinkPermission[] | undefined) ?? ['view'],\n maxExpiryDays: typeof raw.maxExpiryDays === 'number' ? raw.maxExpiryDays : undefined,\n redactFields: Array.isArray(raw.redactFields) ? (raw.redactFields as string[]) : [],\n };\n}\n\n/** Parse `expiresAt` as either an ISO string or a relative duration like \"7d\", \"24h\", \"30m\". */\nfunction normaliseExpiresAt(input: string | null | undefined, maxDays: number): string | null {\n if (!input) return null;\n const now = Date.now();\n const cap = now + maxDays * 86_400_000;\n\n // Relative duration shorthand.\n const m = /^([0-9]+)(s|m|h|d)$/i.exec(input);\n if (m) {\n const n = Number(m[1]);\n const unit = m[2].toLowerCase();\n const ms = unit === 's' ? n * 1000 : unit === 'm' ? n * 60_000 : unit === 'h' ? n * 3_600_000 : n * 86_400_000;\n const at = now + ms;\n if (at > cap) {\n throw makeError(422, 'EXPIRY_TOO_LONG', `expiresAt exceeds the object's max of ${maxDays} days`);\n }\n return new Date(at).toISOString();\n }\n\n // Otherwise expect an ISO timestamp.\n const t = Date.parse(input);\n if (Number.isNaN(t)) {\n throw makeError(422, 'INVALID_EXPIRY', `expiresAt is not a valid ISO timestamp or duration: ${input}`);\n }\n if (t > cap) {\n throw makeError(422, 'EXPIRY_TOO_LONG', `expiresAt exceeds the object's max of ${maxDays} days`);\n }\n if (t <= now) {\n throw makeError(422, 'EXPIRY_IN_PAST', 'expiresAt must be in the future');\n }\n return new Date(t).toISOString();\n}\n\n/**\n * Weak password hash. Production deployments should swap in argon2 /\n * bcrypt via dependency injection (see `ShareLinkServiceOptions.hashPassword`).\n * The default uses SubtleCrypto SHA-256 with a per-row salt — strong\n * enough to keep the hash useless to a casual observer and to deflate\n * the cost of a database leak, but NOT a substitute for argon2 against\n * a determined attacker. The platform deliberately surfaces this in the\n * plugin docs so deployments can decide.\n */\nasync function defaultHashPassword(password: string): Promise<string> {\n const g: any = globalThis as any;\n const subtle = g.crypto?.subtle;\n const salt = generateToken(16);\n if (!subtle) {\n // Synthetic fallback — no SubtleCrypto means we're in a stripped\n // runtime; emit a clearly-marked placeholder so the deployment is\n // forced to wire in a real hasher rather than ship a weak one.\n return `weak$${salt}$${password}`;\n }\n const enc = new TextEncoder();\n const buf = await subtle.digest('SHA-256', enc.encode(salt + ':' + password));\n const hex = Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `sha256$${salt}$${hex}`;\n}\n\nasync function defaultVerifyPassword(password: string, hash: string): Promise<boolean> {\n if (hash.startsWith('weak$')) {\n const [, , stored] = hash.split('$');\n return stored === password;\n }\n if (hash.startsWith('sha256$')) {\n const [, salt, expected] = hash.split('$');\n const g: any = globalThis as any;\n const subtle = g.crypto?.subtle;\n if (!subtle) return false;\n const enc = new TextEncoder();\n const buf = await subtle.digest('SHA-256', enc.encode(salt + ':' + password));\n const hex = Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return hex === expected;\n }\n return false;\n}\n\nfunction makeError(status: number, code: string, message: string): Error {\n const err: any = new Error(message);\n err.status = status;\n err.code = code;\n return err;\n}\n\nexport interface ShareLinkServiceOptions {\n engine: SharingEngine;\n /** Override the default SHA-256 hasher with argon2 / bcrypt for production. */\n hashPassword?: (plain: string) => Promise<string>;\n /** Companion verifier — must accept hashes produced by `hashPassword`. */\n verifyPassword?: (plain: string, hash: string) => Promise<boolean>;\n /**\n * Bypass the per-object opt-in check (useful when the schema scan is\n * happening after `start`). When omitted, calls against an object\n * without `publicSharing.enabled=true` are rejected with 422.\n */\n permissive?: boolean;\n}\n\n/**\n * Default `IShareLinkService` implementation.\n *\n * Persists every link in `sys_share_link`. The companion REST routes\n * (`registerShareLinkRoutes`) thin-wrap the service; the public\n * `/api/v1/share-links/:token` route resolves and re-injects the\n * \"share-link principal\" into the execution context so the standard\n * data middleware can authorise the downstream read.\n */\nexport class ShareLinkService implements IShareLinkService {\n private readonly engine: SharingEngine;\n private readonly permissive: boolean;\n private readonly hashPassword: (plain: string) => Promise<string>;\n private readonly verifyPassword: (plain: string, hash: string) => Promise<boolean>;\n\n constructor(opts: ShareLinkServiceOptions) {\n this.engine = opts.engine;\n this.permissive = opts.permissive ?? false;\n this.hashPassword = opts.hashPassword ?? defaultHashPassword;\n this.verifyPassword = opts.verifyPassword ?? defaultVerifyPassword;\n }\n\n async createLink(\n input: CreateShareLinkInput,\n context: ShareLinkExecutionContext,\n ): Promise<ShareLink> {\n if (!input.object) throw makeError(400, 'VALIDATION_FAILED', 'object is required');\n if (!input.recordId) throw makeError(400, 'VALIDATION_FAILED', 'recordId is required');\n\n const schema = this.engine.getSchema?.(input.object);\n const policy = getPolicy(schema);\n\n if (!policy.enabled && !this.permissive && !context.isSystem) {\n throw makeError(\n 422,\n 'SHARING_NOT_ENABLED',\n `Object '${input.object}' has not enabled publicSharing in its schema`,\n );\n }\n\n const permission: ShareLinkPermission = input.permission ?? 'view';\n if (policy.enabled && policy.allowedPermissions.length > 0 && !policy.allowedPermissions.includes(permission)) {\n throw makeError(\n 422,\n 'PERMISSION_NOT_ALLOWED',\n `Object '${input.object}' does not allow share permission '${permission}'. Allowed: ${policy.allowedPermissions.join(', ')}`,\n );\n }\n\n const audience: ShareLinkAudience = input.audience ?? 'link_only';\n if (policy.enabled && policy.allowedAudiences.length > 0 && !policy.allowedAudiences.includes(audience)) {\n throw makeError(\n 422,\n 'AUDIENCE_NOT_ALLOWED',\n `Object '${input.object}' does not allow audience '${audience}'. Allowed: ${policy.allowedAudiences.join(', ')}`,\n );\n }\n\n if (audience === 'email' && (!input.emailAllowlist || input.emailAllowlist.length === 0)) {\n throw makeError(400, 'VALIDATION_FAILED', 'emailAllowlist is required when audience=email');\n }\n\n // Confirm the target record actually exists — silently issuing\n // links against ghost rows is a footgun.\n const exists = await this.engine.find(input.object, {\n where: { id: input.recordId },\n fields: ['id'],\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n if (!Array.isArray(exists) || exists.length === 0) {\n throw makeError(404, 'RECORD_NOT_FOUND', `${input.object}/${input.recordId} does not exist`);\n }\n\n const maxDays = policy.maxExpiryDays ?? DEFAULT_MAX_EXPIRY_DAYS;\n const expires_at = normaliseExpiresAt(input.expiresAt, maxDays);\n\n const passwordHash = input.password ? await this.hashPassword(input.password) : null;\n\n const row: ShareLink = {\n id: `shl_${generateToken(16)}`,\n token: generateToken(TOKEN_LENGTH),\n object_name: input.object,\n record_id: input.recordId,\n permission,\n audience,\n expires_at,\n email_allowlist:\n input.emailAllowlist && input.emailAllowlist.length > 0\n ? input.emailAllowlist.map((e) => e.trim().toLowerCase()).filter(Boolean)\n : null,\n password_hash: passwordHash,\n redact_fields: input.redactFields && input.redactFields.length > 0 ? input.redactFields : null,\n label: input.label ?? null,\n revoked_at: null,\n created_by: context.userId ?? null,\n created_at: new Date().toISOString(),\n last_used_at: null,\n use_count: 0,\n };\n\n await this.engine.insert('sys_share_link', row, { context: SYSTEM_CTX });\n return row;\n }\n\n async revokeLink(idOrToken: string, _context: ShareLinkExecutionContext): Promise<void> {\n if (!idOrToken) throw makeError(400, 'VALIDATION_FAILED', 'id or token is required');\n const filter = idOrToken.startsWith('shl_') ? { id: idOrToken } : { token: idOrToken };\n const rows = await this.engine.find('sys_share_link', {\n where: filter,\n fields: ['id', 'revoked_at'],\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const row = Array.isArray(rows) ? (rows[0] as any) : undefined;\n if (!row) return; // No-op when missing\n if (row.revoked_at) return; // Already revoked\n await this.engine.update(\n 'sys_share_link',\n { id: row.id, revoked_at: new Date().toISOString() },\n { context: SYSTEM_CTX },\n );\n }\n\n async listLinks(\n filter: ListShareLinksFilter,\n context: ShareLinkExecutionContext,\n ): Promise<ShareLink[]> {\n const where: Record<string, unknown> = {};\n if (filter.object) where.object_name = filter.object;\n if (filter.recordId) where.record_id = filter.recordId;\n if (filter.createdBy) where.created_by = filter.createdBy;\n if (!filter.includeRevoked) where.revoked_at = null;\n\n const rows = await this.engine.find('sys_share_link', {\n where,\n limit: 200,\n sort: [{ field: 'created_at', order: 'desc' }],\n context: context.isSystem ? SYSTEM_CTX : context,\n } as any);\n return Array.isArray(rows) ? (rows as ShareLink[]) : [];\n }\n\n async resolveToken(\n token: string,\n probe: { signedInUserId?: string; recipientEmail?: string; providedPassword?: string } = {},\n ): Promise<ResolveShareLinkResult | null> {\n if (!token || typeof token !== 'string' || token.length < 8) return null;\n\n const rows = await this.engine.find('sys_share_link', {\n where: { token },\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const row = Array.isArray(rows) ? (rows[0] as ShareLink | undefined) : undefined;\n if (!row) return null;\n\n if (row.revoked_at) return null;\n if (row.expires_at && Date.parse(row.expires_at) <= Date.now()) return null;\n\n // Audience gating.\n if (row.audience === 'signed_in' && !probe.signedInUserId) return null;\n if (row.audience === 'email') {\n const allow = row.email_allowlist ?? [];\n const supplied = (probe.recipientEmail ?? '').trim().toLowerCase();\n if (!supplied || !allow.includes(supplied)) return null;\n }\n\n if (row.password_hash) {\n if (!probe.providedPassword) return null;\n const ok = await this.verifyPassword(probe.providedPassword, row.password_hash);\n if (!ok) return null;\n }\n\n // Compute the effective redaction set (object default ∪ per-link).\n const schema = this.engine.getSchema?.(row.object_name);\n const policy = getPolicy(schema);\n const redactFields = Array.from(\n new Set<string>([...(policy.redactFields ?? []), ...((row.redact_fields as string[]) ?? [])]),\n );\n\n // Stamp usage. Errors here MUST NOT block the read — log-and-continue.\n try {\n await this.engine.update(\n 'sys_share_link',\n {\n id: row.id,\n last_used_at: new Date().toISOString(),\n use_count: (row.use_count ?? 0) + 1,\n },\n { context: SYSTEM_CTX },\n );\n } catch {\n // best-effort — usage telemetry is a nice-to-have\n }\n\n return { link: row, redactFields };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * REST surface for ShareLinkService.\n *\n * POST /api/v1/share-links → create a link\n * GET /api/v1/share-links → list links (?object, ?recordId, ?includeRevoked)\n * DELETE /api/v1/share-links/:idOrToken → revoke\n * GET /api/v1/share-links/:token/resolve → resolve token, returns { record, link, redactFields }\n *\n * The resolve route is intentionally public — it's the only endpoint\n * holders of a token need. It does:\n *\n * 1. Look up the row by token (via ShareLinkService.resolveToken,\n * which gates audience / expiry / password and stamps usage).\n * 2. Fetch the underlying record with a SYSTEM context (so the read\n * bypasses normal RLS — the token IS the authorisation).\n * 3. Strip `redactFields` from the record before returning.\n *\n * For browser-rendered share pages, the front-end calls this endpoint\n * and renders the response read-only.\n */\n\nimport type { IHttpServer, IHttpRequest, IHttpResponse, RouteHandler } from '@objectstack/spec/contracts';\nimport type { ShareLinkExecutionContext } from '@objectstack/spec/contracts';\nimport type { ShareLinkService } from './share-link-service.js';\nimport type { SharingEngine } from './sharing-service.js';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\nexport interface ShareLinkRoutesOptions {\n basePath?: string;\n /** Read caller identity for authenticated routes. */\n contextFromRequest?: (req: IHttpRequest) => ShareLinkExecutionContext;\n}\n\nconst defaultContext = (req: IHttpRequest): ShareLinkExecutionContext => {\n const header = (name: string): string | undefined => {\n const v = req.headers?.[name];\n return Array.isArray(v) ? v[0] : v;\n };\n return {\n userId: header('x-user-id'),\n tenantId: header('x-tenant-id'),\n };\n};\n\nfunction sendError(res: IHttpResponse, status: number, code: string, message: string) {\n res.status(status).json({ error: { code, message } });\n}\n\n/** Strip `redactFields` from a record (also removes from nested arrays of objects). */\nfunction applyRedaction(record: any, redactFields: string[]): any {\n if (!record || typeof record !== 'object' || redactFields.length === 0) return record;\n if (Array.isArray(record)) return record.map((r) => applyRedaction(r, redactFields));\n const out: any = {};\n for (const [k, v] of Object.entries(record)) {\n if (redactFields.includes(k)) continue;\n out[k] = v;\n }\n return out;\n}\n\nexport function registerShareLinkRoutes(\n http: IHttpServer,\n service: ShareLinkService,\n engine: SharingEngine,\n opts: ShareLinkRoutesOptions = {},\n): void {\n const base = opts.basePath ?? '/api/v1/share-links';\n const ctxOf = opts.contextFromRequest ?? defaultContext;\n\n // ── CREATE ─────────────────────────────────────────────────────\n http.post(base, (async (req, res) => {\n try {\n const ctx = ctxOf(req);\n const body: any = req.body ?? {};\n if (!body.object || !body.recordId) {\n return sendError(res, 400, 'VALIDATION_FAILED', 'object and recordId are required');\n }\n const link = await service.createLink(\n {\n object: body.object,\n recordId: body.recordId,\n permission: body.permission,\n audience: body.audience,\n expiresAt: body.expiresAt ?? null,\n emailAllowlist: body.emailAllowlist,\n password: body.password,\n redactFields: body.redactFields,\n label: body.label,\n },\n ctx,\n );\n // Echo the token in the create response only — the listing\n // endpoint also returns it (admins need to copy/recreate URLs),\n // but downstream API consumers typically derive the public URL\n // from `link.token` immediately.\n await res.status(201).json({ link });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to create link');\n }\n }) satisfies RouteHandler);\n\n // ── LIST ───────────────────────────────────────────────────────\n http.get(base, (async (req, res) => {\n try {\n const ctx = ctxOf(req);\n const q = req.query ?? {};\n const link = await service.listLinks(\n {\n object: typeof q.object === 'string' ? q.object : undefined,\n recordId: typeof q.recordId === 'string' ? q.recordId : undefined,\n createdBy: typeof q.createdBy === 'string' ? q.createdBy : undefined,\n includeRevoked: q.includeRevoked === 'true' || q.includeRevoked === '1',\n },\n ctx,\n );\n await res.json({ links: link });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to list links');\n }\n }) satisfies RouteHandler);\n\n // ── REVOKE ─────────────────────────────────────────────────────\n http.delete(`${base}/:idOrToken`, (async (req, res) => {\n try {\n const ctx = ctxOf(req);\n await service.revokeLink(req.params.idOrToken, ctx);\n await res.status(200).json({ ok: true });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to revoke link');\n }\n }) satisfies RouteHandler);\n\n // ── PUBLIC RESOLVE ────────────────────────────────────────────\n //\n // No `ctxOf` here — the token IS the authorisation. We still allow\n // probes from a signed-in user so audience=signed_in is satisfiable.\n http.get(`${base}/:token/resolve`, (async (req, res) => {\n try {\n const q = req.query ?? {};\n const signedInUserId = (() => {\n const v = req.headers?.['x-user-id'];\n return Array.isArray(v) ? v[0] : v;\n })();\n const recipientEmail = typeof q.email === 'string' ? q.email : undefined;\n const providedPassword =\n typeof q.password === 'string'\n ? q.password\n : (() => {\n const v = req.headers?.['x-share-password'];\n return Array.isArray(v) ? v[0] : v;\n })();\n\n const resolved = await service.resolveToken(req.params.token, {\n signedInUserId,\n recipientEmail,\n providedPassword,\n });\n if (!resolved) {\n // Probe row to give a more useful status code (401 vs 404 vs 410).\n const probe = await engine.find('sys_share_link', {\n where: { token: req.params.token },\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const row = Array.isArray(probe) && probe[0] ? (probe[0] as any) : null;\n if (row && !row.revoked_at && (!row.expires_at || Date.parse(row.expires_at) > Date.now())) {\n if (row.password_hash) {\n return sendError(\n res,\n 401,\n providedPassword ? 'WRONG_PASSWORD' : 'NEEDS_PASSWORD',\n providedPassword ? 'Incorrect password' : 'This link requires a password',\n );\n }\n if (row.audience === 'signed_in' && !signedInUserId) {\n return sendError(res, 401, 'SIGN_IN_REQUIRED', 'Please sign in to view this link');\n }\n }\n if (row && (row.revoked_at || (row.expires_at && Date.parse(row.expires_at) <= Date.now()))) {\n return sendError(res, 410, 'EXPIRED_OR_REVOKED', 'Share link has expired or been revoked');\n }\n return sendError(res, 404, 'INVALID_OR_EXPIRED', 'Share link is invalid, expired, or revoked');\n }\n\n // Fetch the underlying record with system context — the token\n // gates access, RLS does not.\n const rows = await engine.find(resolved.link.object_name, {\n where: { id: resolved.link.record_id },\n limit: 1,\n context: SYSTEM_CTX,\n } as any);\n const record = Array.isArray(rows) && rows[0] ? rows[0] : null;\n if (!record) {\n return sendError(res, 410, 'RECORD_GONE', 'The shared record no longer exists');\n }\n\n await res.json({\n record: applyRedaction(record, resolved.redactFields),\n link: {\n id: resolved.link.id,\n token: resolved.link.token,\n object_name: resolved.link.object_name,\n record_id: resolved.link.record_id,\n permission: resolved.link.permission,\n audience: resolved.link.audience,\n expires_at: resolved.link.expires_at,\n label: resolved.link.label,\n created_at: resolved.link.created_at,\n },\n redactFields: resolved.redactFields,\n });\n } catch (err: any) {\n sendError(res, err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Failed to resolve link');\n }\n }) satisfies RouteHandler);\n\n // ──────────────────────────────────────────────────────────────\n // Object-specific related-records lookup.\n //\n // Some objects only make sense alongside their children — most\n // notably `ai_conversations` and the `ai_messages` they own. Rather\n // than baking every relationship into the resolver, we expose a\n // narrow, opt-in `GET /:token/messages` route that:\n //\n // 1. Re-validates the capability token (so revocation / expiry\n // kicks in even after the original resolve).\n // 2. Confirms the shared record really is an `ai_conversations`.\n // 3. Returns the conversation's messages, ordered by creation.\n //\n // Other object kinds can register additional public endpoints\n // following the same pattern.\n // ──────────────────────────────────────────────────────────────\n http.get(`${base}/:token/messages`, (async (req, res) => {\n try {\n const password =\n typeof req.query?.password === 'string' ? (req.query.password as string) : undefined;\n const resolved = await service.resolveToken(req.params.token, { providedPassword: password });\n if (!resolved) {\n sendError(res, 404, 'NOT_FOUND', 'Share link not found');\n return;\n }\n if (resolved.link.object_name !== 'ai_conversations') {\n sendError(res, 400, 'UNSUPPORTED', 'This share link does not expose messages');\n return;\n }\n const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n const rows = await engine.find('ai_messages', {\n where: { conversation_id: resolved.link.record_id },\n sort: [{ field: 'created_at', order: 'asc' }],\n limit: 500,\n context: SYSTEM_CTX,\n } as any);\n res.status(200).json({ data: rows ?? [] });\n } catch (err: any) {\n sendError(\n res,\n err?.status ?? 500,\n err?.code ?? 'INTERNAL',\n err?.message ?? 'Failed to load messages',\n );\n }\n }) satisfies RouteHandler);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { SharingRuleService } from './sharing-rule-service.js';\nimport type { SharingRuleRow } from '@objectstack/spec/contracts';\n\nconst SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n\nexport const SHARING_RULE_HOOK_PACKAGE = 'plugin-sharing:rules';\n\ninterface MinimalEngine {\n registerHook(event: string, handler: (ctx: any) => any | Promise<any>, options?: {\n object?: string | string[];\n priority?: number;\n packageId?: string;\n }): void;\n unregisterHooksByPackage(packageId: string): number;\n}\n\ninterface MinimalLogger {\n info?: (msg: any, ...rest: any[]) => void;\n warn?: (msg: any, ...rest: any[]) => void;\n}\n\n/**\n * Bind afterInsert/afterUpdate hooks for every distinct object_name in\n * `rules`. Each hook calls `service.evaluateAllForRecord(object, id, …)`\n * with SYSTEM_CTX so the evaluator can write `sys_record_share` rows\n * without being blocked by its own enforcement.\n *\n * Caller is responsible for invoking {@link unbindAllRuleHooks} before\n * re-binding when the rule set changes.\n */\nexport function bindRuleHooks(\n engine: MinimalEngine,\n service: SharingRuleService,\n rules: SharingRuleRow[],\n logger?: MinimalLogger,\n): void {\n const objects = new Set<string>();\n for (const r of rules) {\n if (r.active === false) continue;\n if (r.object_name) objects.add(r.object_name);\n }\n for (const objectName of objects) {\n const handler = async (ctx: any) => {\n if ((ctx?.session as any)?.isSystem) return;\n try {\n const data = ctx?.result ?? ctx?.input?.data ?? {};\n const id = String((data as any)?.id ?? ctx?.input?.id ?? '');\n if (!id) return;\n await service.evaluateAllForRecord(objectName, id, SYSTEM_CTX as any);\n } catch (err: any) {\n logger?.warn?.('[sharing-rule] hook evaluation failed', { object: objectName, error: err?.message });\n }\n };\n engine.registerHook('afterInsert', handler, { object: objectName, packageId: SHARING_RULE_HOOK_PACKAGE, priority: 180 });\n engine.registerHook('afterUpdate', handler, { object: objectName, packageId: SHARING_RULE_HOOK_PACKAGE, priority: 180 });\n }\n logger?.info?.('[sharing-rule] hooks bound', { objects: Array.from(objects), ruleCount: rules.length });\n}\n\nexport function unbindAllRuleHooks(engine: MinimalEngine): number {\n return engine.unregisterHooksByPackage(SHARING_RULE_HOOK_PACKAGE);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport type { EngineMiddleware, OperationContext } from '@objectstack/objectql';\nimport type { IHttpServer } from '@objectstack/spec/contracts';\nimport { SysRecordShare, SysSharingRule, SysShareLink } from './objects/index.js';\nimport { SysDepartment, SysDepartmentMember } from '@objectstack/platform-objects/identity';\nimport { SharingService, type SharingEngine } from './sharing-service.js';\nimport { SharingRuleService } from './sharing-rule-service.js';\nimport { ShareLinkService } from './share-link-service.js';\nimport { registerShareLinkRoutes } from './share-link-routes.js';\nimport { bindRuleHooks, unbindAllRuleHooks } from './rule-hooks.js';\n\nexport interface SharingPluginOptions {\n /** Extra object names that bypass sharing entirely. */\n bypassObjects?: string[];\n /**\n * Disable enforcement (read filter + canEdit) while still registering\n * the schema + service. Useful in development to flip enforcement on\n * via env var without rebuilding.\n */\n enforce?: boolean;\n /**\n * Disable the public share-link REST routes. The `IShareLinkService`\n * is always registered (other services may depend on it); only the\n * HTTP surface is suppressed.\n */\n registerShareLinkRoutes?: boolean;\n /**\n * Base path for the share-link REST surface. Defaults to\n * `/api/v1/share-links`.\n */\n shareLinkBasePath?: string;\n}\n\n/**\n * SharingServicePlugin — registers `sys_record_share`, the `sharing`\n * service, and the engine middleware that enforces\n * `object.sharingModel`.\n *\n * Enforcement is opt-in per object:\n *\n * - `sharingModel: 'private'` → reads filtered to `(owner_id == me) OR\n * (record explicitly shared with me)`. Writes require ownership or\n * an `edit`/`full` share.\n * - `sharingModel: 'read'` → reads unrestricted; writes gated as\n * above (typical \"everyone can see, only owner can edit\").\n * - any other value (or no value) → no enforcement. This keeps\n * existing CRM behaviour identical until admins explicitly enable\n * sharing on a per-object basis.\n *\n * @example\n * ```ts\n * import { SharingServicePlugin } from '@objectstack/plugin-sharing';\n *\n * kernel.use(new SharingServicePlugin());\n *\n * // Mark an object private — middleware enforces from this point on.\n * defineObject({\n * name: 'account',\n * sharingModel: 'private',\n * fields: { owner_id: Field.lookup('sys_user'), ... },\n * });\n * ```\n */\nexport class SharingServicePlugin implements Plugin {\n name = 'com.objectstack.service.sharing';\n version = '1.0.0';\n type = 'standard';\n dependencies = ['com.objectstack.engine.objectql'];\n\n private readonly options: SharingPluginOptions;\n private service?: SharingService;\n private ruleService?: SharingRuleService;\n private linkService?: ShareLinkService;\n\n constructor(options: SharingPluginOptions = {}) {\n this.options = options;\n }\n\n async init(ctx: PluginContext): Promise<void> {\n // Register sys_record_share via the manifest service.\n ctx.getService<{ register(m: any): void }>('manifest').register({\n id: 'com.objectstack.service.sharing',\n name: 'Sharing Service',\n version: '1.0.0',\n type: 'plugin',\n scope: 'system',\n defaultDatasource: 'cloud',\n namespace: 'sys',\n objects: [SysRecordShare, SysSharingRule, SysDepartment, SysDepartmentMember, SysShareLink],\n // ADR-0029 D7 — contribute the sharing entries into the Setup app's\n // `group_access_control` slot (priority 200 so they sit after plugin-\n // security's Roles / Permission Sets). This plugin owns these objects (K2).\n navigationContributions: [\n {\n app: 'setup',\n group: 'group_access_control',\n priority: 200,\n items: [\n { id: 'nav_sharing_rules', type: 'object', label: 'Sharing Rules', objectName: 'sys_sharing_rule', icon: 'share-2', requiresObject: 'sys_sharing_rule', requiredPermissions: ['manage_platform_settings'] },\n { id: 'nav_record_shares', type: 'object', label: 'Record Shares', objectName: 'sys_record_share', icon: 'link', requiresObject: 'sys_record_share', requiredPermissions: ['manage_platform_settings'] },\n ],\n },\n ],\n });\n\n // ADR-0029 D8 — contribute this plugin's object translations to the i18n\n // service on kernel:ready (the i18n plugin may register after this one).\n if (typeof (ctx as any).hook === 'function') {\n (ctx as any).hook('kernel:ready', async () => {\n try {\n const i18n = ctx.getService<any>('i18n');\n if (i18n && typeof i18n.loadTranslations === 'function') {\n const { SharingTranslations } = await import('./translations/index.js');\n for (const [locale, data] of Object.entries(SharingTranslations)) {\n i18n.loadTranslations(locale, data as Record<string, unknown>);\n }\n }\n } catch { /* i18n optional */ }\n });\n }\n ctx.logger.info('SharingServicePlugin: schema registered');\n }\n\n async start(ctx: PluginContext): Promise<void> {\n ctx.hook('kernel:ready', async () => {\n let engine: any = null;\n try { engine = ctx.getService<any>('objectql'); }\n catch { try { engine = ctx.getService<any>('data'); } catch { /* ignore */ } }\n if (!engine) {\n ctx.logger.warn('SharingServicePlugin: no ObjectQL engine — service NOT registered');\n return;\n }\n\n this.service = new SharingService({\n engine: engine as SharingEngine,\n bypassObjects: this.options.bypassObjects,\n });\n ctx.registerService('sharing', this.service);\n\n // Enforcement (read-filter middleware + sharing-rule hooks) is opt-out\n // via `enforce: false`. The share-link service below is registered\n // REGARDLESS — capability-token sharing does not depend on principal-\n // based RLS enforcement, and multi-tenant hosts mount this plugin purely\n // for the `shareLinks` service (per-env enforcement is applied elsewhere).\n if (this.options.enforce === false) {\n ctx.logger.info('SharingServicePlugin: enforcement disabled (enforce=false) — share-link service still registered');\n } else {\n const mw = buildSharingMiddleware(this.service);\n if (typeof engine.registerMiddleware === 'function') {\n engine.registerMiddleware(mw, { object: '*' });\n ctx.logger.info('SharingServicePlugin: enforcement middleware installed');\n } else {\n ctx.logger.warn('SharingServicePlugin: engine has no registerMiddleware — enforcement not applied');\n }\n\n // Rule evaluator + hot-rebindable lifecycle hooks.\n try {\n this.ruleService = new SharingRuleService({\n engine: engine as SharingEngine,\n sharing: this.service,\n logger: ctx.logger as any,\n });\n ctx.registerService('sharingRules', this.ruleService);\n\n if (typeof engine.registerHook === 'function' && typeof engine.unregisterHooksByPackage === 'function') {\n const rules = await this.ruleService.listRules({ activeOnly: true }, { isSystem: true } as any);\n unbindAllRuleHooks(engine);\n bindRuleHooks(engine, this.ruleService, rules, ctx.logger as any);\n } else {\n ctx.logger.warn('SharingServicePlugin: engine has no hook API — sharing rule auto-evaluation disabled');\n }\n } catch (err: any) {\n ctx.logger.warn('SharingServicePlugin: sharing-rule subsystem not started', { error: err?.message });\n }\n }\n\n // ── Share-Link service (capability tokens) ────────────────\n //\n // Registered alongside the principal-based sharing service so\n // both surfaces resolve through the same kernel. The HTTP\n // endpoints are optional — services that just want programmatic\n // access can set `registerShareLinkRoutes: false` and call the\n // service via `ctx.getService('shareLinks')`.\n try {\n this.linkService = new ShareLinkService({ engine: engine as SharingEngine });\n ctx.registerService('shareLinks', this.linkService);\n\n if (this.options.registerShareLinkRoutes !== false) {\n let http: IHttpServer | null = null;\n try {\n http = ctx.getService<IHttpServer>('http-server');\n } catch {\n // No HTTP server — service still reachable via getService.\n }\n if (http) {\n registerShareLinkRoutes(http, this.linkService, engine as SharingEngine, {\n basePath: this.options.shareLinkBasePath,\n });\n ctx.logger.info(\n 'SharingServicePlugin: share-link routes mounted at ' +\n (this.options.shareLinkBasePath ?? '/api/v1/share-links'),\n );\n } else {\n ctx.logger.warn(\n 'SharingServicePlugin: no HTTP server — share-link REST routes not registered. ' +\n 'ShareLinkService is still reachable via kernel.getService(\"shareLinks\").',\n );\n }\n }\n } catch (err: any) {\n ctx.logger.warn('SharingServicePlugin: share-link subsystem not started', { error: err?.message });\n }\n });\n }\n}\n\n/**\n * Build the engine middleware that injects read filters and gates\n * write operations. Exported so it can be unit-tested without booting\n * a kernel.\n */\nexport function buildSharingMiddleware(service: SharingService): EngineMiddleware {\n return async function sharingMiddleware(ctx: OperationContext, next: () => Promise<void>) {\n const op = ctx.operation;\n const exec = ctx.context as any;\n\n // READS — AND the visibility filter into the AST.\n if (op === 'find' || op === 'findOne' || op === 'count' || op === 'aggregate') {\n const filter = await service.buildReadFilter(ctx.object, exec ?? {});\n if (filter) {\n const ast: any = ctx.ast ?? {};\n ast.where = composeAnd(ast.where, filter);\n ast.filter = composeAnd(ast.filter, filter);\n ctx.ast = ast;\n }\n return next();\n }\n\n // WRITES — gate on canEdit for update / delete.\n if (op === 'update' || op === 'delete') {\n const data: any = ctx.data;\n const options: any = ctx.options;\n const id = inferTargetId(data, options);\n if (id != null) {\n const ok = await service.canEdit(ctx.object, String(id), exec ?? {});\n if (!ok) {\n const err: any = new Error(\n `FORBIDDEN: insufficient privileges to ${op} ${ctx.object} ${id}`,\n );\n err.code = 'FORBIDDEN';\n err.status = 403;\n throw err;\n }\n }\n return next();\n }\n\n // INSERT / others pass through — ownership stamping is the\n // application's job (and is enforced by existing field defaults).\n return next();\n };\n}\n\nfunction composeAnd(existing: unknown, addition: unknown): unknown {\n if (existing == null) return addition;\n if (addition == null) return existing;\n // Both objects — merge with $and.\n if (\n typeof existing === 'object' && existing !== null && !Array.isArray(existing) &&\n typeof addition === 'object' && addition !== null && !Array.isArray(addition)\n ) {\n const ex: any = existing;\n if (Array.isArray(ex.$and)) {\n return { $and: [...ex.$and, addition] };\n }\n // Heuristic: if existing has no operator keys, attempt shallow merge;\n // otherwise nest into $and to preserve semantics.\n return { $and: [existing, addition] };\n }\n return { $and: [existing, addition] };\n}\n\nfunction inferTargetId(data: any, options: any): string | number | undefined {\n if (data && typeof data === 'object' && data.id != null) return data.id;\n if (options && typeof options === 'object') {\n if (options.id != null) return options.id;\n if (options.where && typeof options.where === 'object' && options.where.id != null) {\n return options.where.id;\n }\n if (options.filter && typeof options.filter === 'object' && options.filter.id != null) {\n return options.filter.id;\n }\n }\n return undefined;\n}\n"],"mappings":"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","names":["import_data","import_data","import_identity","row","SYSTEM_CTX","SYSTEM_CTX","uid","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SYSTEM_CTX","SharingTranslations"]}