@aiquants/auth-directory-drizzle 0.4.0 → 0.5.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.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -1158,8 +1158,22 @@ declare function findLedgerRowsForIdentity(db: DirectoryDb, tables: LedgerIdenti
|
|
|
1158
1158
|
* 忘れることを構造的に不可能にする。
|
|
1159
1159
|
*/
|
|
1160
1160
|
type LinkableAssertion = {
|
|
1161
|
-
/**
|
|
1162
|
-
|
|
1161
|
+
/**
|
|
1162
|
+
* Owns a transaction, proves the group may be linked on it, then runs `write` on the same runner.
|
|
1163
|
+
* トランザクションを所有し、その上で連携可能であることを証明してから、同じランナーで `write` を実行する処理。
|
|
1164
|
+
*
|
|
1165
|
+
* ⚠️ **証明だけを返す形にしてはならない。** 証明と連携の作成が別のトランザクションだと、
|
|
1166
|
+
* 証明を通った直後・リンクを作る前に、そのグループへ管理ロールを割り当てる操作が
|
|
1167
|
+
* 割り込める。割り当て側の検査は「まだリンクが無い」と見て通り、連携側の検査は
|
|
1168
|
+
* 「まだ管理ロールが無い」と見て通る — **どちらも単独では正しく、結果だけが不変条件を破る**。
|
|
1169
|
+
*
|
|
1170
|
+
* @param tenantId - Tenant that owns the group. グループを所有するテナント。
|
|
1171
|
+
* @param groupId - Group about to become externally sourced. 外部供給にしようとしているグループ。
|
|
1172
|
+
* @param write - The link creation, run on the proving transaction. 証明したトランザクション上で行う連携作成。
|
|
1173
|
+
* @returns Nothing. 戻り値なし。
|
|
1174
|
+
* @throws When the group holds an administrative role. 管理ロールを保持している場合。
|
|
1175
|
+
*/
|
|
1176
|
+
assertLinkableAndWrite(tenantId: string, groupId: number, write: (runner: unknown) => Promise<void>): Promise<void>;
|
|
1163
1177
|
};
|
|
1164
1178
|
/** Options for the link store. リンクストアの構成。 */
|
|
1165
1179
|
type DirectoryLinkStoreOptions = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1158,8 +1158,22 @@ declare function findLedgerRowsForIdentity(db: DirectoryDb, tables: LedgerIdenti
|
|
|
1158
1158
|
* 忘れることを構造的に不可能にする。
|
|
1159
1159
|
*/
|
|
1160
1160
|
type LinkableAssertion = {
|
|
1161
|
-
/**
|
|
1162
|
-
|
|
1161
|
+
/**
|
|
1162
|
+
* Owns a transaction, proves the group may be linked on it, then runs `write` on the same runner.
|
|
1163
|
+
* トランザクションを所有し、その上で連携可能であることを証明してから、同じランナーで `write` を実行する処理。
|
|
1164
|
+
*
|
|
1165
|
+
* ⚠️ **証明だけを返す形にしてはならない。** 証明と連携の作成が別のトランザクションだと、
|
|
1166
|
+
* 証明を通った直後・リンクを作る前に、そのグループへ管理ロールを割り当てる操作が
|
|
1167
|
+
* 割り込める。割り当て側の検査は「まだリンクが無い」と見て通り、連携側の検査は
|
|
1168
|
+
* 「まだ管理ロールが無い」と見て通る — **どちらも単独では正しく、結果だけが不変条件を破る**。
|
|
1169
|
+
*
|
|
1170
|
+
* @param tenantId - Tenant that owns the group. グループを所有するテナント。
|
|
1171
|
+
* @param groupId - Group about to become externally sourced. 外部供給にしようとしているグループ。
|
|
1172
|
+
* @param write - The link creation, run on the proving transaction. 証明したトランザクション上で行う連携作成。
|
|
1173
|
+
* @returns Nothing. 戻り値なし。
|
|
1174
|
+
* @throws When the group holds an administrative role. 管理ロールを保持している場合。
|
|
1175
|
+
*/
|
|
1176
|
+
assertLinkableAndWrite(tenantId: string, groupId: number, write: (runner: unknown) => Promise<void>): Promise<void>;
|
|
1163
1177
|
};
|
|
1164
1178
|
/** Options for the link store. リンクストアの構成。 */
|
|
1165
1179
|
type DirectoryLinkStoreOptions = {
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var F=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var ce=(t,o)=>{for(var h in o)F(t,h,{get:o[h],enumerable:!0})},me=(t,o,h,b)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of le(o))!pe.call(t,s)&&s!==h&&F(t,s,{get:()=>o[s],enumerable:!(b=ue(o,s))||b.enumerable});return t};var ye=t=>me(F({},"__esModule",{value:!0}),t);var Me={};ce(Me,{AUTH_DIRECTORY_PROVIDER_COLUMN:()=>se,AUTH_DIRECTORY_TENANT_SCOPED_TABLES:()=>ve,MAX_IN_LIST:()=>ze,MAX_PARAMETERS:()=>ie,MEMBERSHIP_MODES:()=>Y,UNHEALTHY_SYNC_OUTCOMES:()=>Z,assertGroupMayBeLinked:()=>be,assertMembershipMode:()=>K,chunk:()=>L,chunkByParameters:()=>N,createDirectoryLinkStore:()=>we,createDirectorySync:()=>De,createDirectorySyncRepository:()=>Ee,createPromotionRepository:()=>Ae,createSyncRequestQueue:()=>xe,defaultExternalGroupGuardMessage:()=>ge,defaultSyncMessages:()=>Q,defineAuthDirectorySchema:()=>Te,findLedgerRowsForIdentity:()=>q,promoteLedgerForUser:()=>fe,withExternalGroupGuards:()=>he});module.exports=ye(Me);var te=require("@aiquants/authz-core"),ge=(t,o)=>`\u5916\u90E8\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u9023\u643A\u30B0\u30EB\u30FC\u30D7 (${o}) \u306B\u306F\u7BA1\u7406\u30ED\u30FC\u30EB (${t}) \u3092\u6301\u305F\u305B\u3089\u308C\u307E\u305B\u3093\u3002\u4E0A\u6D41\u5074\u306E\u6240\u5C5E\u5909\u66F4\u304C\u305D\u306E\u307E\u307E\u7BA1\u7406\u8005\u306E\u5897\u6E1B\u306B\u306A\u308B\u305F\u3081\u3001\u7BA1\u7406\u8005\u7D4C\u8DEF\u306F\u30ED\u30FC\u30AB\u30EB\u7BA1\u7406\u306E\u30B0\u30EB\u30FC\u30D7\u306B\u9650\u5B9A\u3057\u3066\u3044\u307E\u3059\u3002`;function H(t,o,h,b){return new Set(t.filter(s=>s.roleId===o&&s.appKey===h&&s.resourceKey===b).map(s=>s.action))}var J=t=>te.AUTHZ_ACTIONS.every(o=>t.has(o)),V=(t,o)=>t.find(h=>h.roleId===o)?.roleKey??`#${o}`;function he(t,o){let h=t;async function b(s,a,p,y,w){if(y.size===0)return;let n=await s.listGroupRoles(p),g=new Set;for(let e of n){if(!y.has(e.roleId)||g.has(e.groupId))continue;g.add(e.groupId);let l=await o.linkLookup.externalGroupKey(p,e.groupId,a);if(l!==null)throw new Error(o.message(e.roleKey||V(w,e.roleId),l))}}return{...t,async assignGroupRole(s,a,p,y){await h.withTransaction(async(w,n)=>{let g=await w.listGrants(s);if(J(H(g,p,o.adminAppKey,o.adminResourceKey))){let e=await o.linkLookup.externalGroupKey(s,a,n);if(e!==null)throw new Error(o.message(V(g,p),e))}await w.assignGroupRole(s,a,p,y)})},async createGrant(s,a,p){await h.withTransaction(async(y,w)=>{let g=(await y.listResources(s)).find(e=>e.id===a.resourceId);if(g?.appKey===o.adminAppKey&&g?.resourceKey===o.adminResourceKey){let e=await y.listGrants(s),l=H(e,a.roleId,o.adminAppKey,o.adminResourceKey);l.add(a.action),J(l)&&await b(y,w,s,new Set([a.roleId]),e)}await y.createGrant(s,a,p)})}}}async function be(t,o,h,b){let s=(await t.listGroupRoles(o)).filter(p=>p.groupId===h);if(s.length===0)return;let a=await t.listGrants(o);for(let p of s)if(J(H(a,p.roleId,b.adminAppKey,b.adminResourceKey)))throw new Error(b.message(p.roleKey||V(a,p.roleId),p.groupKey))}var $=require("drizzle-orm");async function q(t,o,h){let{ledger:b,group:s}=o,{tenantId:a,externalUserId:p,email:y}=h;if(p===null&&y==="")return[];let w={ledgerId:b.id,groupId:b.groupId,tenantId:s.tenantId,externalUserId:b.externalUserId},n=async d=>(await t.select(w).from(b).innerJoin(s,(0,$.and)((0,$.eq)(s.id,b.groupId),(0,$.eq)(s.tenantId,a),(0,$.eq)(s.isActive,!0))).where(d)).map(I=>({ledgerId:Number(I.ledgerId),groupId:Number(I.groupId),tenantId:String(I.tenantId),externalUserId:I.externalUserId===null?null:String(I.externalUserId)})),g=d=>{let v=new Map;for(let I of d)v.set(I.ledgerId,{ledgerId:I.ledgerId,groupId:I.groupId,tenantId:I.tenantId});return[...v.values()].sort((I,T)=>I.ledgerId-T.ledgerId)},e=p===null?[]:await n((0,$.eq)(b.externalUserId,p));if(y==="")return g(e);let l=await n((0,$.eq)(b.email,y)),S=d=>p!==null&&d.externalUserId!==null&&d.externalUserId!==p;return g([...e,...l.filter(d=>!S(d))])}var O=require("@aiquants/auth-core"),ne=require("@aiquants/auth-directory-core"),x=require("@aiquants/authz-core"),u=require("drizzle-orm");var Y=["direct","transitive"];function K(t){if(!Y.includes(t))throw new TypeError(`[@aiquants/auth-directory-drizzle] membershipMode must be one of ${Y.join(" | ")}, received ${JSON.stringify(t)}`);return t}function we(t,o,h,b){let s=t,a=b.ensureConnection??(async()=>{}),p=b.policyCacheTtlMs??0;if(!Number.isFinite(p)||p<0)throw new TypeError(`[@aiquants/auth-directory-drizzle] policyCacheTtlMs must be a non-negative number, received ${String(b.policyCacheTtlMs)}`);let y=new Map,w=r=>y.delete(r),{TDGroupExternalLink:n,TDGroupMemberEmail:g,TDTenantMembershipGroup:e,TDAllowlistGroup:l,TDDirectorySyncRequest:S}=o,{TMGroup:d,TDGroupMember:v}=h;async function I(r,i,m){if((await r.select({groupId:e.groupId}).from(e).where((0,u.and)((0,u.eq)(e.tenantId,i),(0,u.eq)(e.groupId,m),(0,u.eq)(e.isBreakGlass,!0)))).length>0)throw new Error(`Group ${m} is a break-glass proof group; a break-glass proof path must be one the synchronization can never touch.`)}async function T(r,i,m){let[f]=await r.select({id:d.id}).from(d).where((0,u.and)((0,u.eq)(d.id,m),(0,u.eq)(d.tenantId,i)));if(!f)throw new Error(`Group not found in tenant: ${m}`)}function G(r,i){return{linkId:Number(r.linkId),groupId:Number(r.groupId),tenantId:String(r.tenantId),provider:String(r.provider),externalId:String(r.externalId),externalKey:String(r.externalKey),membershipMode:K(String(r.membershipMode)),isSyncEnabled:!!r.isSyncEnabled,...r.syncedAt?{syncedAt:new Date(r.syncedAt).toISOString()}:{},...r.syncError?{syncError:String(r.syncError)}:{},unresolvedCount:i}}async function _(r,i){let m=await r.select({groupId:g.groupId,n:(0,u.count)()}).from(g).innerJoin(d,(0,u.and)((0,u.eq)(d.id,g.groupId),(0,u.eq)(d.tenantId,i))).where((0,u.isNull)(g.resolvedUserId)).groupBy(g.groupId);return new Map(m.map(f=>[Number(f.groupId),Number(f.n)]))}return{async listLinks(r){(0,x.assertTenantId)(r,"listLinks(tenantId)"),await a();let i=await s.select({linkId:n.id,groupId:n.groupId,tenantId:n.tenantId,provider:n.provider,externalId:n.externalId,externalKey:n.externalKey,membershipMode:n.membershipMode,isSyncEnabled:n.isSyncEnabled,syncedAt:n.syncedAt,syncError:n.syncError}).from(n).where((0,u.eq)(n.tenantId,r)).orderBy((0,u.asc)(n.groupId)),m=await _(s,r);return i.map(f=>((0,x.assertTenantMatch)(r,String(f.tenantId),"listLinks(row.tenantId)"),G(f,m.get(Number(f.groupId))??0)))},async externalGroupKey(r,i,m){(0,x.assertTenantId)(r,"externalGroupKey(tenantId)"),await a();let[f]=await(m??s).select({externalKey:n.externalKey}).from(n).where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)));return f?String(f.externalKey):null},async linkGroup(r,i,m,f){(0,x.assertTenantId)(r,"linkGroup(tenantId)");let D=K(m.membershipMode),k=m.externalId.trim(),E=(0,O.normalizeAuthEmail)(m.externalKey);if(k===""||E==="")throw new TypeError("[@aiquants/auth-directory-drizzle] externalId and externalKey must be non-empty");await a(),await b.linkable.assertLinkable(r,i),await s.transaction(async z=>{await T(z,r,i),await I(z,r,i),await z.insert(n).output().values({groupId:i,tenantId:r,provider:m.provider,externalId:k,externalKey:E,membershipMode:D,isSyncEnabled:!0,vanishedObservations:0,createdAt:new Date,createdBy:f})}),w(r)},async unlinkGroup(r,i){(0,x.assertTenantId)(r,"unlinkGroup(tenantId)"),await a(),await s.transaction(async m=>{await T(m,r,i),await m.delete(g).where((0,u.eq)(g.groupId,i)),await m.delete(l).where((0,u.and)((0,u.eq)(l.groupId,i),(0,u.eq)(l.tenantId,r))),await m.delete(n).where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)))}),w(r)},async setSyncEnabled(r,i,m,f){(0,x.assertTenantId)(r,"setSyncEnabled(tenantId)"),await a(),await s.update(n).set({isSyncEnabled:m,updatedAt:new Date,updatedBy:f}).output().where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)))},async requestSync(r,i,m){(0,x.assertTenantId)(r,"requestSync(tenantId)"),await a(),await s.transaction(async f=>{i!==null&&await T(f,r,i),await f.insert(S).output().values({tenantId:r,groupId:i,requestedBy:m,requestedAt:new Date,createdAt:new Date,createdBy:m})})},async getStatus(r){(0,x.assertTenantId)(r,"getStatus(tenantId)"),await a();let i=await s.select({groupId:n.groupId,isSyncEnabled:n.isSyncEnabled,syncedAt:n.syncedAt,syncError:n.syncError}).from(n).where((0,u.eq)(n.tenantId,r)),[m]=await s.select({n:(0,u.count)()}).from(S).where((0,u.and)((0,u.eq)(S.tenantId,r),(0,u.isNull)(S.finishedAt))),f=i.filter(R=>!!R.isSyncEnabled),D=f.map(R=>R.syncedAt?new Date(R.syncedAt).getTime():null),k=D.length>0&&D.every(R=>R!==null)?Math.min(...D):null,z=i.length>0&&f.length===0||f.length>0&&(k===null||Date.now()-k>b.stalenessThresholdSec*1e3);return{isEnabled:b.isEnabled,linkedGroupCount:i.length,...k!==null?{oldestSyncedAt:new Date(k).toISOString()}:{},isStale:z,pausedGroupCount:i.length-f.length,stalenessThresholdSec:b.stalenessThresholdSec,erroredGroupIds:i.filter(R=>!!R.syncError).map(R=>Number(R.groupId)).sort((R,de)=>R-de),pendingRequestCount:Number(m?.n??0)}},async loadTenantMembershipPolicy(r){(0,x.assertTenantId)(r,"loadTenantMembershipPolicy(tenantId)");let i=p>0?y.get(r):void 0;if(i&&Date.now()-i.loadedAt<p)return i.policy;await a();let m=await s.select({groupId:e.groupId,isBreakGlass:e.isBreakGlass,externalLinkId:n.id}).from(e).innerJoin(d,(0,u.and)((0,u.eq)(d.id,e.groupId),(0,u.eq)(d.tenantId,r))).leftJoin(n,(0,u.eq)(n.groupId,e.groupId)).where((0,u.eq)(e.tenantId,r));if(m.length===0){let E={kind:"no-proof-required"};return p>0&&y.set(r,{policy:E,loadedAt:Date.now()}),E}let f=m.map(E=>Number(E.groupId)),D=m.filter(E=>!!E.isBreakGlass);for(let E of D)if(E.externalLinkId!==null)throw new Error(`Break-glass group ${Number(E.groupId)} is externally sourced; a break-glass proof path must be one the synchronization can never touch.`);let k={kind:"require-proof",proofGroupIds:f,breakGlassGroupIds:D.map(E=>Number(E.groupId))};return(0,ne.assertTenantMembershipPolicy)(k,`tenant ${r}`),p>0&&y.set(r,{policy:k,loadedAt:Date.now()}),k},async setTenantMembershipGroup(r,i,m,f){(0,x.assertTenantId)(r,"setTenantMembershipGroup(tenantId)"),await a(),await s.transaction(async D=>{if(await T(D,r,i),m){let[E]=await D.select({id:n.id}).from(n).where((0,u.and)((0,u.eq)(n.tenantId,r),(0,u.eq)(n.groupId,i)));if(E)throw new Error(`Group ${i} is externally sourced; a break-glass proof path must be one the synchronization can never touch.`)}if((await D.select({groupId:e.groupId}).from(e).where((0,u.and)((0,u.eq)(e.tenantId,r),(0,u.eq)(e.groupId,i)))).length>0){await D.update(e).set({isBreakGlass:m,updatedAt:new Date,updatedBy:f}).output().where((0,u.and)((0,u.eq)(e.tenantId,r),(0,u.eq)(e.groupId,i))),w(r);return}await D.insert(e).output().values({tenantId:r,groupId:i,isBreakGlass:m,createdAt:new Date,createdBy:f})}),w(r)},async removeTenantMembershipGroup(r,i){(0,x.assertTenantId)(r,"removeTenantMembershipGroup(tenantId)"),await a(),await s.transaction(async m=>{let D=(await m.select({groupId:e.groupId,isBreakGlass:e.isBreakGlass}).from(e).where((0,u.eq)(e.tenantId,r))).filter(k=>Number(k.groupId)!==i);if(D.length>0&&!D.some(k=>!!k.isBreakGlass))throw new Error(`Removing group ${i} would leave tenant ${r} with a membership proof but no break-glass path.`);await m.delete(e).where((0,u.and)((0,u.eq)(e.tenantId,r),(0,u.eq)(e.groupId,i)))}),w(r)},async setGroupActive(r,i,m,f){(0,x.assertTenantId)(r,"setGroupActive(tenantId)"),await a(),await s.update(d).set({isActive:m,updatedAt:new Date,updatedBy:f}).output().where((0,u.and)((0,u.eq)(d.id,i),(0,u.eq)(d.tenantId,r)))},async listLedgerGroupIds(r,i){if((0,x.assertTenantId)(r,"listLedgerGroupIds(tenantId)"),!b.isEnabled)return[];await a();let m=await q(s,{ledger:g,group:d},{tenantId:r,externalUserId:i.externalUserId?.trim()||null,email:(0,O.normalizeAuthEmail)(i.email)});return[...new Set(m.map(f=>f.groupId))].sort((f,D)=>f-D)},async isEmailAllowedByGroup(r){if(!b.isEnabled)return!1;let i=(0,O.normalizeAuthEmail)(r);if(i==="")return!1;await a();let[m]=await s.select({id:g.id}).from(g).innerJoin(l,(0,u.eq)(l.groupId,g.groupId)).innerJoin(d,(0,u.and)((0,u.eq)(d.id,g.groupId),(0,u.eq)(d.isActive,!0))).where((0,u.eq)(g.email,i));return!!m},async listAllowlistGroups(r){return(0,x.assertTenantId)(r,"listAllowlistGroups(tenantId)"),await a(),(await s.select({id:l.id,groupId:l.groupId,groupKey:d.groupKey,groupName:d.name,description:l.description}).from(l).innerJoin(d,(0,u.and)((0,u.eq)(d.id,l.groupId),(0,u.eq)(d.tenantId,r))).where((0,u.eq)(l.tenantId,r)).orderBy((0,u.asc)(d.name))).map(m=>({id:Number(m.id),type:"group",groupId:Number(m.groupId),groupKey:String(m.groupKey),groupName:String(m.groupName),...m.description?{description:String(m.description)}:{},owner:{kind:"tenant",tenantId:r},readOnly:!1}))},async addAllowlistGroup(r,i,m,f){(0,x.assertTenantId)(r,"addAllowlistGroup(tenantId)"),await a(),await s.transaction(async D=>{await T(D,r,i);let[k]=await D.select({id:n.id}).from(n).where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)));if(!k)throw new Error(`Group ${i} is locally managed; only externally-sourced groups can gate sign-in, because the decision reads the upstream member ledger.`);await D.insert(l).output().values({tenantId:r,groupId:i,description:m??null,createdAt:new Date,createdBy:f})})},async removeAllowlistGroup(r,i){(0,x.assertTenantId)(r,"removeAllowlistGroup(tenantId)"),await a(),await s.delete(l).where((0,u.and)((0,u.eq)(l.id,i),(0,u.eq)(l.tenantId,r)))},async countProjectedMembers(r,i){(0,x.assertTenantId)(r,"countProjectedMembers(tenantId)"),await a();let[m]=await s.select({n:(0,u.count)()}).from(v).innerJoin(d,(0,u.and)((0,u.eq)(d.id,v.groupId),(0,u.eq)(d.tenantId,r))).where((0,u.eq)(v.groupId,i));return Number(m?.n??0)}}}var oe=require("@aiquants/auth-core"),C=require("@aiquants/authz-core");async function fe(t,o){let h=(0,C.assertTenantId)(o.tenantId,"promoteLedgerForUser(tenantId)");if(!Number.isInteger(o.userId)||o.userId<=0)throw new TypeError(`[@aiquants/auth-directory-drizzle] userId must be a positive integer, received ${String(o.userId)}`);let b=(0,oe.normalizeAuthEmail)(o.email),s=o.externalUserId?.trim()||null;if(s===null&&b==="")return{addedGroupIds:[],matchedLedgerIds:[]};let a=await t.findLedgerMatches({tenantId:h,externalUserId:s,email:b});if(a.length===0)return{addedGroupIds:[],matchedLedgerIds:[]};for(let n of a)(0,C.assertTenantMatch)(h,n.tenantId,"promoteLedgerForUser(findLedgerMatches row)");let p=[...new Set(a.map(n=>n.ledgerId))].sort((n,g)=>n-g),y=[...new Set(a.map(n=>n.groupId))].sort((n,g)=>n-g);return{addedGroupIds:[...await t.attachUserToGroups({tenantId:h,userId:o.userId,ledgerIds:p,groupIds:y})].sort((n,g)=>n-g),matchedLedgerIds:p}}var W=require("@aiquants/authz-core"),M=require("drizzle-orm");var ie=2100;var ze=500;function L(t,o=500){if(!Number.isInteger(o)||o<=0)throw new TypeError(`[@aiquants/auth-directory-drizzle] chunk size must be a positive integer, received ${String(o)}`);let h=[];for(let b=0;b<t.length;b+=o)h.push(t.slice(b,b+o));return h}function N(t,o,h=100){if(!Number.isInteger(o)||o<=0)throw new TypeError(`[@aiquants/auth-directory-drizzle] parametersPerItem must be a positive integer, received ${String(o)}`);if(!Number.isInteger(h)||h<0)throw new TypeError(`[@aiquants/auth-directory-drizzle] reservedParameters must be a non-negative integer, received ${String(h)}`);let b=2100-h,s=Math.floor(b/o);if(s<1)throw new TypeError(`[@aiquants/auth-directory-drizzle] a single item binds ${o} parameters, which exceeds the ${b} available in one statement`);return L(t,s)}var Ie=4,Se=100;function Ae(t,o,h,b){let s=t,a=b.ensureConnection??(async()=>{}),p=b.now??(()=>new Date),y=o.TDGroupMemberEmail,{TMGroup:w,TDGroupMember:n}=h;return{async findLedgerMatches(g){return(0,W.assertTenantId)(g.tenantId,"findLedgerMatches(tenantId)"),await a(),q(s,{ledger:y,group:w},g)},async attachUserToGroups({tenantId:g,userId:e,ledgerIds:l,groupIds:S}){return(0,W.assertTenantId)(g,"attachUserToGroups(tenantId)"),await a(),l.length===0?[]:s.transaction(async d=>{let v=new Set;for(let r of L(S)){let i=await d.select({id:w.id}).from(w).where((0,M.and)((0,M.inArray)(w.id,r),(0,M.eq)(w.tenantId,g),(0,M.eq)(w.isActive,!0)));for(let m of i)v.add(Number(m.id))}let I=S.filter(r=>v.has(r));if(I.length===0)return[];let T=new Set;for(let r of L(I)){let i=await d.select({groupId:n.groupId}).from(n).where((0,M.and)((0,M.eq)(n.userId,e),(0,M.inArray)(n.groupId,r)));for(let m of i)T.add(Number(m.groupId))}let G=I.filter(r=>!T.has(r)),_=Math.max(1,2100-Se-I.length);for(let r of L(l,_))await d.update(y).set({resolvedUserId:e}).output().where((0,M.and)((0,M.inArray)(y.id,r),(0,M.inArray)(y.groupId,I)));if(G.length>0){let r=p();for(let i of N(G,Ie))await d.insert(n).output().values(i.map(m=>({groupId:m,userId:e,createdAt:r,createdBy:b.actor})))}return G})}}}var U=require("@aiquants/authz-drizzle"),c=require("drizzle-orm/mssql-core"),se="provider",ve=["TDGroupExternalLink","TDTenantMembershipGroup","TDAllowlistGroup","TDDirectorySyncRequest","TMAllowlist"];function Te(t,o){let h=(0,c.mssqlSchema)(t),b=()=>({createdAt:(0,c.datetime2)("created_at"),createdBy:(0,c.nvarchar)("created_by",{length:50}),updatedAt:(0,c.datetime2)("updated_at"),updatedBy:(0,c.nvarchar)("updated_by",{length:50})}),s=()=>({createdAt:(0,c.datetime2)("created_at"),createdBy:(0,c.nvarchar)("created_by",{length:50})}),a=h.table("TDGroupExternalLink",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),provider:(0,c.nvarchar)(se,{length:32}).notNull(),externalId:(0,c.nvarchar)("external_id",{length:256}).notNull(),externalKey:(0,c.nvarchar)("external_key",{length:320}).notNull(),membershipMode:(0,c.nvarchar)("membership_mode",{length:16}).notNull(),isSyncEnabled:(0,c.bit)("is_sync_enabled").notNull(),syncedAt:(0,c.datetime2)("synced_at"),syncError:(0,c.nvarchar)("sync_error",{length:1e3}),vanishedObservations:(0,c.int)("vanished_observations").notNull(),...b()},e=>[(0,c.primaryKey)({name:`${t}_TDGroupExternalLink_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TDGroupExternalLink_group_uq`).on(e.groupId),(0,c.uniqueIndex)(`${t}_TDGroupExternalLink_external_uq`).on(e.tenantId,e.provider,e.externalId),(0,c.foreignKey)({name:`${t}_TDGroupExternalLink_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),p=h.table("TDGroupMemberEmail",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),email:(0,c.nvarchar)("email",{length:320}).notNull(),externalUserId:(0,c.nvarchar)("external_user_id",{length:128}),resolvedUserId:(0,c.bigint)("resolved_user_id",{mode:"number"}),observedAt:(0,c.datetime2)("observed_at").notNull(),...b()},e=>[(0,c.primaryKey)({name:`${t}_TDGroupMemberEmail_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TDGroupMemberEmail_group_email_uq`).on(e.groupId,e.email),(0,c.foreignKey)({name:`${t}_TDGroupMemberEmail_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),y=h.table("TDTenantMembershipGroup",{tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),isBreakGlass:(0,c.bit)("is_break_glass").notNull(),...s()},e=>[(0,c.primaryKey)({name:`${t}_TDTenantMembershipGroup_pk`,columns:[e.tenantId,e.groupId]}),(0,c.foreignKey)({name:`${t}_TDTenantMembershipGroup_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),w=h.table("TDAllowlistGroup",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),description:(0,c.nvarchar)("description",{length:512}),...s()},e=>[(0,c.primaryKey)({name:`${t}_TDAllowlistGroup_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TDAllowlistGroup_tenant_group_uq`).on(e.tenantId,e.groupId),(0,c.foreignKey)({name:`${t}_TDAllowlistGroup_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),n=h.table("TDDirectorySyncRequest",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}),requestedBy:(0,c.nvarchar)("requested_by",{length:320}).notNull(),requestedAt:(0,c.datetime2)("requested_at").notNull(),pickedAt:(0,c.datetime2)("picked_at"),finishedAt:(0,c.datetime2)("finished_at"),result:(0,c.nvarchar)("result",{length:32}),error:(0,c.nvarchar)("error",{length:2e3}),...s()},e=>[(0,c.primaryKey)({name:`${t}_TDDirectorySyncRequest_pk`,columns:[e.id]})]),g=h.table("TMAllowlist",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),pattern:(0,c.nvarchar)("pattern",{length:256}).notNull(),type:(0,c.nvarchar)("type",{length:32}).notNull(),description:(0,c.nvarchar)("description",{length:512}),...s()},e=>[(0,c.primaryKey)({name:`${t}_TMAllowlist_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TMAllowlist_pattern_uq`).on(e.tenantId,e.pattern)]);return{TDGroupExternalLink:a,TDGroupMemberEmail:p,TDTenantMembershipGroup:y,TDAllowlistGroup:w,TDDirectorySyncRequest:n,TMAllowlist:g}}var j=require("@aiquants/auth-directory-core");var X=(t,o=20)=>t.length<=o?t.join(", "):`${t.slice(0,o).join(", ")} \u307B\u304B ${t.length-o} \u4EF6`,Q={upstreamUnreadable:t=>`\u4E0A\u6D41\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u8AAD\u307F\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${t}`,localWriteFailed:t=>`\u30ED\u30FC\u30AB\u30EB\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${t}`,resolverIncomplete:(t,o)=>`\u4E0A\u6D41\u304C ${t} \u4EF6\u306E\u30E1\u30F3\u30D0\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F\u304C\u3001\u7A81\u5408\u7D50\u679C\u306F ${o} \u4EF6\u3067\u3057\u305F\u3002\u4EF6\u6570\u304C\u6E1B\u308B\u7A81\u5408\u306F\u3001\u89E3\u6C7A\u3067\u304D\u306A\u304B\u3063\u305F\u4EBA\u7269\u3092\u300C\u4E0A\u6D41\u304B\u3089\u6D88\u3048\u305F\u300D\u3068\u3057\u3066\u524A\u9664\u3057\u3066\u3057\u307E\u3046\u305F\u3081\u4E2D\u65AD\u3057\u307E\u3057\u305F\u3002\u89E3\u6C7A\u3067\u304D\u306A\u3044\u30E1\u30F3\u30D0\u30FC\u306F\u7701\u7565\u305B\u305A resolvedUserId: null \u3067\u8FD4\u3059\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002`,groupMissing:(t,o,h)=>`\u4E0A\u6D41\u3067\u30B0\u30EB\u30FC\u30D7\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t})\u3002\u9023\u7D9A ${o} \u56DE\u76EE\u3067\u3059\u3002${h} \u56DE\u306B\u9054\u3057\u305F\u6642\u70B9\u3067\u30B0\u30EB\u30FC\u30D7\u3092\u7121\u52B9\u5316\u3057\u307E\u3059\u3002`,groupVanished:(t,o)=>`\u4E0A\u6D41\u3067\u30B0\u30EB\u30FC\u30D7\u304C ${o} \u56DE\u9023\u7D9A\u3067\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F (${t})\u3002\u30B0\u30EB\u30FC\u30D7\u3092\u7121\u52B9\u5316\u3057\u307E\u3057\u305F\u3002\u4E0A\u6D41\u304C\u5FA9\u65E7\u3059\u308C\u3070\u6B21\u56DE\u306E\u540C\u671F\u3067\u81EA\u52D5\u7684\u306B\u518D\u6709\u52B9\u5316\u3055\u308C\u307E\u3059\u3002`,planRefused:t=>{if(t.reason==="invalid-upstream-data")return`\u540C\u671F\u3092\u4E2D\u65AD\u3057\u307E\u3057\u305F: \u4E0A\u6D41\u306E\u30E1\u30F3\u30D0\u30FC\u4E00\u89A7\u306B\u6271\u3048\u306A\u3044\u30A2\u30C9\u30EC\u30B9\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059 (${X(t.offendingEmails)})\u3002`;let o=t.axis==="membership"?"\u6A29\u9650\u3092\u5931\u3046\u4EBA\u6570":"\u30B5\u30A4\u30F3\u30A4\u30F3\u3067\u304D\u306A\u304F\u306A\u308B\u4EBA\u6570",h=t.axis==="membership"?t.withheldProjectionRemoves.map(String):t.withheldLedgerDeletes;return[`\u540C\u671F\u3092\u4E2D\u65AD\u3057\u307E\u3057\u305F: ${o}\u304C ${t.population} \u4EBA\u4E2D ${t.removalCount} \u4EBA\u306B\u306A\u308A\u307E\u3059`,`(\u4E0A\u9650: ${t.limits.maxRemovalCount} \u4EF6 / \u6BD4\u7387 ${t.limits.maxRemovalRatio})\u3002`,`\u5DEE\u3057\u6B62\u3081\u305F\u5BFE\u8C61: ${X(h)}\u3002`,"\u4E0A\u6D41\u5074\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u610F\u56F3\u3057\u305F\u5909\u66F4\u3067\u3042\u308C\u3070\u3001\u3053\u306E\u8EF8\u306E\u4E0A\u9650\u3060\u3051\u3092\u4E00\u6642\u7684\u306B\u5F15\u304D\u4E0A\u3052\u3066\u518D\u5B9F\u884C\u3057\u307E\u3059\u3002"].join(" ")},removalsRefused:t=>`${t.length} \u4EF6\u306E\u6240\u5C5E\u89E3\u9664\u304C\u6700\u5F8C\u306E\u7BA1\u7406\u8005\u30AC\u30FC\u30C9\u306B\u3088\u308A\u62D2\u5426\u3055\u308C\u307E\u3057\u305F (\u30E6\u30FC\u30B6\u30FC ${X(t.map(o=>String(o.userId)))})\u3002\u6B8B\u308A\u306E\u5909\u66F4\u306F\u9069\u7528\u6E08\u307F\u3067\u3059\u3002`,foreignProvider:(t,o)=>`\u3053\u306E\u30EA\u30F3\u30AF\u306E\u4F9B\u7D66\u5143\u306F ${t} \u3067\u3059\u304C\u3001\u5B9F\u884C\u4E2D\u306E\u540C\u671F\u306F ${o} \u7528\u3067\u3059\u3002\u5BFE\u5FDC\u3059\u308B\u540C\u671F\u30B8\u30E7\u30D6\u304B\u3089\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`};var Z=["aborted","missing","vanished","upstream-failed","local-failed","foreign-provider"];function De(t){let{directory:o,repository:h,policy:b,now:s,logger:a}=t,p=t.messages??Q;if((0,j.assertBlastRadiusPolicy)(b),!Number.isInteger(t.vanishedThreshold)||t.vanishedThreshold<1)throw new TypeError(`[@aiquants/auth-directory-drizzle] vanishedThreshold must be a positive integer, received ${String(t.vanishedThreshold)}`);if(typeof t.provider!="string"||t.provider.trim()==="")throw new TypeError("[@aiquants/auth-directory-drizzle] provider must be a non-empty string so links of other providers can be told apart");async function y(e,l){try{await h.recordFailure(e,l)}catch(S){a.error(`[auth-directory] could not record the failure for ${e.externalKey}:`,S)}}async function w(e){try{let l=await o.getGroup(e.externalId);return l===null?{kind:"missing"}:{kind:"ok",group:l,members:await o.listGroupMembers(l,e.membershipMode)}}catch(l){return{kind:"failed",error:l instanceof Error?l:new Error(String(l))}}}async function n(e){let l=await h.recordVanishedObservation(e,p.groupMissing(e.externalKey,e.vanishedObservations+1,t.vanishedThreshold));return l<t.vanishedThreshold?(a.warn(`[auth-directory] ${e.externalKey} missing upstream (${l}/${t.vanishedThreshold})`),{kind:"missing",link:e,observations:l}):(await h.markGroupInactive(e),await y(e,p.groupVanished(e.externalKey,l)),a.warn(`[auth-directory] ${e.externalKey} deactivated after ${l} consecutive absences`),{kind:"vanished",link:e})}async function g(e){if(e.provider!==t.provider)return await y(e,p.foreignProvider(e.provider,t.provider)),a.warn(`[auth-directory] skipping ${e.externalKey}: belongs to provider ${e.provider}`),{kind:"foreign-provider",link:e};let l=await w(e);if(l.kind==="missing")return n(e);if(l.kind==="failed")return await y(e,p.upstreamUnreadable(l.error.message)),a.error(`[auth-directory] upstream read failed for ${e.externalKey}:`,l.error),{kind:"upstream-failed",link:e,error:l.error};try{let[S,d]=await Promise.all([h.loadGroupSnapshot(e),h.resolveMembers(l.members)]);if(d.length!==l.members.length){let _=p.resolverIncomplete(l.members.length,d.length);return await y(e,_),a.error(`[auth-directory] ${_}`),{kind:"local-failed",link:e,error:new Error(_)}}let v=(0,j.reconcile)(S,d,b);if(v.aborted)return await y(e,p.planRefused(v.aborted)),a.warn(`[auth-directory] plan refused for ${e.externalKey}: ${v.aborted.reason}`),{kind:"aborted",link:e,plan:v};let I=v.ledgerUpserts.length>0||v.ledgerDeletes.length>0||v.projectionAdds.length>0||v.projectionRemoves.length>0,T=s(),G={refusals:[]};return I&&(G=await h.applyPlan(e,v,T)),await h.recordSuccess(e,l.group,T),G.refusals.length>0&&(await y(e,p.removalsRefused(G.refusals)),a.warn(`[auth-directory] ${G.refusals.length} removal(s) refused for ${e.externalKey}`)),v.unresolvedEmails.length>0&&a.info(`[auth-directory] ${e.externalKey}: ${v.unresolvedEmails.length} upstream member(s) have no local user yet`),I?{kind:"applied",link:e,plan:v}:{kind:"unchanged",link:e}}catch(S){let d=S instanceof Error?S:new Error(String(S));return await y(e,p.localWriteFailed(d.message)),a.error(`[auth-directory] local write failed for ${e.externalKey}:`,d),{kind:"local-failed",link:e,error:d}}}return{syncOne:g,async run(e={}){let l=await h.listSyncableLinks(e),S=[];for(let v of l)try{S.push(await g(v))}catch(I){let T=I instanceof Error?I:new Error(String(I));a.error(`[auth-directory] ${v.externalKey} ended abnormally:`,T),S.push({kind:"local-failed",link:v,error:T})}let d=S.filter(v=>Z.includes(v.kind)).length;return a.info(`[auth-directory] run finished: ${S.length} link(s), ${d} unhealthy`),{outcomes:S,unhealthyCount:d}}}}var ae=require("@aiquants/authz-core"),P=require("drizzle-orm"),ee=2e3;function xe(t,o,h){let b=t,s=h.ensureConnection??(async()=>{}),a=o.TDDirectorySyncRequest,p=h.maxErrorLength??ee;if(!Number.isInteger(p)||p<1||p>ee)throw new TypeError(`[@aiquants/auth-directory-drizzle] maxErrorLength must be an integer within 1..${ee}, received ${String(h.maxErrorLength)}`);return{async claim(){await s();let y=await b.select({id:a.id}).from(a).where((0,P.isNull)(a.pickedAt)).orderBy((0,P.asc)(a.id));for(let w of y){let g=(await b.update(a).set({pickedAt:h.now()}).output().where((0,P.and)((0,P.eq)(a.id,Number(w.id)),(0,P.isNull)(a.pickedAt))))?.[0];if(!g)continue;let e=String(g.tenant_id??g.tenantId??""),l=g.group_id??g.groupId??null;return{id:Number(g.id),tenantId:(0,ae.assertTenantId)(e,"claim(row.tenantId)"),groupId:l===null?null:Number(l),requestedBy:String(g.requested_by??g.requestedBy??"")}}return null},async finish(y,w){await s();let n=w.error?w.error.slice(0,p):null;await b.update(a).set({finishedAt:h.now(),result:w.result,error:n}).output().where((0,P.eq)(a.id,y))},async listStranded(y){return await s(),(await b.select({id:a.id,pickedAt:a.pickedAt}).from(a).where((0,P.isNull)(a.finishedAt)).orderBy((0,P.asc)(a.id))).filter(n=>n.pickedAt!==null&&new Date(n.pickedAt)<y).map(n=>Number(n.id))}}}var re=require("@aiquants/auth-core"),B=require("@aiquants/authz-core"),A=require("drizzle-orm");var ke=7,Ge=4;function Ee(t,o,h,b){let s=t,a=b.ensureConnection??(async()=>{}),{TDGroupExternalLink:p,TDGroupMemberEmail:y}=o,{TMGroup:w,TDGroupMember:n}=h,g=b.actor;return{async listSyncableLinks(e){await a();let l=[(0,A.eq)(p.isSyncEnabled,!0)];return e.tenantId!==void 0&&l.push((0,A.eq)(p.tenantId,(0,B.assertTenantId)(e.tenantId,"listSyncableLinks(tenantId)"))),e.groupId!==void 0&&l.push((0,A.eq)(p.groupId,e.groupId)),(await s.select({linkId:p.id,groupId:p.groupId,linkTenantId:p.tenantId,groupTenantId:w.tenantId,groupKey:w.groupKey,isGroupActive:w.isActive,provider:p.provider,externalId:p.externalId,externalKey:p.externalKey,membershipMode:p.membershipMode,vanishedObservations:p.vanishedObservations}).from(p).innerJoin(w,(0,A.eq)(w.id,p.groupId)).where((0,A.and)(...l))).map(d=>((0,B.assertTenantMatch)(String(d.groupTenantId),String(d.linkTenantId),"listSyncableLinks(link.tenantId vs TMGroup.tenant_id)"),{linkId:Number(d.linkId),groupId:Number(d.groupId),groupKey:String(d.groupKey),tenantId:String(d.groupTenantId),provider:String(d.provider),externalId:String(d.externalId),externalKey:String(d.externalKey),membershipMode:K(String(d.membershipMode)),isGroupActive:!!d.isGroupActive,vanishedObservations:Number(d.vanishedObservations??0)}))},async loadGroupSnapshot(e){await a();let[l,S]=await Promise.all([s.select({email:y.email,externalUserId:y.externalUserId,resolvedUserId:y.resolvedUserId}).from(y).where((0,A.eq)(y.groupId,e.groupId)),s.select({userId:n.userId}).from(n).where((0,A.eq)(n.groupId,e.groupId))]);return{ledger:l.map(d=>({email:String(d.email),...d.externalUserId?{externalUserId:String(d.externalUserId)}:{},resolvedUserId:d.resolvedUserId===null?null:Number(d.resolvedUserId)})),projectedUserIds:S.map(d=>Number(d.userId))}},resolveMembers(e){return b.memberResolver.resolve(e)},async applyPlan(e,l,S){(0,B.assertTenantId)(e.tenantId,"applyPlan(link.tenantId)"),await a(),(l.ledgerUpserts.length>0||l.projectionAdds.length>0)&&await s.transaction(async I=>{let T=l.ledgerUpserts.map(r=>({...r,email:(0,re.normalizeAuthEmail)(r.email)})),G=new Map;for(let r of L(T.map(i=>i.email))){let i=await I.select({id:y.id,email:y.email}).from(y).where((0,A.and)((0,A.eq)(y.groupId,e.groupId),(0,A.inArray)(y.email,r)));for(let m of i)G.set(String(m.email),Number(m.id))}let _=T.filter(r=>!G.has(r.email));for(let r of N(_,ke))await I.insert(y).output().values(r.map(i=>({groupId:e.groupId,email:i.email,externalUserId:i.externalUserId??null,resolvedUserId:i.resolvedUserId,observedAt:S,createdAt:S,createdBy:g})));for(let r of T){let i=G.get(r.email);i!==void 0&&await I.update(y).set({externalUserId:r.externalUserId??null,resolvedUserId:r.resolvedUserId,observedAt:S,updatedAt:S,updatedBy:g}).output().where((0,A.eq)(y.id,i))}for(let r of N(l.projectionAdds,Ge)){let i=new Set((await I.select({userId:n.userId}).from(n).where((0,A.and)((0,A.eq)(n.groupId,e.groupId),(0,A.inArray)(n.userId,r)))).map(f=>Number(f.userId))),m=r.filter(f=>!i.has(f));m.length>0&&await I.insert(n).output().values(m.map(f=>({groupId:e.groupId,userId:f,createdAt:S,createdBy:g})))}});let d=[];for(let I of l.projectionRemoves)try{await b.lockoutGuard.guardedWrite(e.tenantId,{removeGroupMembership:{groupId:e.groupId,userId:I}},"remove-group-member",T=>T.delete(n).where((0,A.and)((0,A.eq)(n.groupId,e.groupId),(0,A.eq)(n.userId,I))))}catch(T){d.push({userId:I,applied:!1,refusal:T instanceof Error?T.message:String(T)})}let v=d.map(I=>I.userId);return l.ledgerDeletes.length>0&&await s.transaction(async I=>{for(let T of L(l.ledgerDeletes)){let G=v.length>0?(0,A.or)((0,A.isNull)(y.resolvedUserId),(0,A.notInArray)(y.resolvedUserId,v)):void 0;await I.delete(y).where((0,A.and)((0,A.eq)(y.groupId,e.groupId),(0,A.inArray)(y.email,T),...G?[G]:[]))}}),{refusals:d}},async recordSuccess(e,l,S){await a(),await s.transaction(async d=>{await d.update(p).set({syncedAt:S,syncError:null,vanishedObservations:0,externalId:l.externalId,externalKey:(0,re.normalizeAuthEmail)(l.externalKey),updatedAt:S,updatedBy:g}).output().where((0,A.eq)(p.id,e.linkId)),e.isGroupActive||await d.update(w).set({isActive:!0,updatedAt:S,updatedBy:g}).output().where((0,A.and)((0,A.eq)(w.id,e.groupId),(0,A.eq)(w.tenantId,e.tenantId)))})},async recordFailure(e,l){await a(),await s.update(p).set({syncError:l.slice(0,1e3),updatedAt:new Date,updatedBy:g}).output().where((0,A.eq)(p.id,e.linkId))},async recordVanishedObservation(e,l){await a();let S=e.vanishedObservations+1;return await s.update(p).set({vanishedObservations:S,syncError:l.slice(0,1e3),updatedAt:new Date,updatedBy:g}).output().where((0,A.eq)(p.id,e.linkId)),S},async markGroupInactive(e){await a(),await s.update(w).set({isActive:!1,updatedAt:new Date,updatedBy:g}).output().where((0,A.and)((0,A.eq)(w.id,e.groupId),(0,A.eq)(w.tenantId,e.tenantId)))}}}0&&(module.exports={AUTH_DIRECTORY_PROVIDER_COLUMN,AUTH_DIRECTORY_TENANT_SCOPED_TABLES,MAX_IN_LIST,MAX_PARAMETERS,MEMBERSHIP_MODES,UNHEALTHY_SYNC_OUTCOMES,assertGroupMayBeLinked,assertMembershipMode,chunk,chunkByParameters,createDirectoryLinkStore,createDirectorySync,createDirectorySyncRepository,createPromotionRepository,createSyncRequestQueue,defaultExternalGroupGuardMessage,defaultSyncMessages,defineAuthDirectorySchema,findLedgerRowsForIdentity,promoteLedgerForUser,withExternalGroupGuards});
|
|
1
|
+
"use strict";var F=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var me=(t,o)=>{for(var g in o)F(t,g,{get:o[g],enumerable:!0})},ye=(t,o,g,b)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of pe(o))!ce.call(t,s)&&s!==g&&F(t,s,{get:()=>o[s],enumerable:!(b=le(o,s))||b.enumerable});return t};var ge=t=>ye(F({},"__esModule",{value:!0}),t);var Re={};me(Re,{AUTH_DIRECTORY_PROVIDER_COLUMN:()=>ae,AUTH_DIRECTORY_TENANT_SCOPED_TABLES:()=>Te,MAX_IN_LIST:()=>qe,MAX_PARAMETERS:()=>se,MEMBERSHIP_MODES:()=>W,UNHEALTHY_SYNC_OUTCOMES:()=>Z,assertGroupMayBeLinked:()=>we,assertMembershipMode:()=>K,chunk:()=>L,chunkByParameters:()=>N,createDirectoryLinkStore:()=>fe,createDirectorySync:()=>xe,createDirectorySyncRepository:()=>Me,createPromotionRepository:()=>ve,createSyncRequestQueue:()=>ke,defaultExternalGroupGuardMessage:()=>he,defaultSyncMessages:()=>Q,defineAuthDirectorySchema:()=>De,findLedgerRowsForIdentity:()=>z,promoteLedgerForUser:()=>Ie,withExternalGroupGuards:()=>be});module.exports=ge(Re);var te=require("@aiquants/authz-core"),he=(t,o)=>`\u5916\u90E8\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u9023\u643A\u30B0\u30EB\u30FC\u30D7 (${o}) \u306B\u306F\u7BA1\u7406\u30ED\u30FC\u30EB (${t}) \u3092\u6301\u305F\u305B\u3089\u308C\u307E\u305B\u3093\u3002\u4E0A\u6D41\u5074\u306E\u6240\u5C5E\u5909\u66F4\u304C\u305D\u306E\u307E\u307E\u7BA1\u7406\u8005\u306E\u5897\u6E1B\u306B\u306A\u308B\u305F\u3081\u3001\u7BA1\u7406\u8005\u7D4C\u8DEF\u306F\u30ED\u30FC\u30AB\u30EB\u7BA1\u7406\u306E\u30B0\u30EB\u30FC\u30D7\u306B\u9650\u5B9A\u3057\u3066\u3044\u307E\u3059\u3002`;function H(t,o,g,b){return new Set(t.filter(s=>s.roleId===o&&s.appKey===g&&s.resourceKey===b).map(s=>s.action))}var J=t=>te.AUTHZ_ACTIONS.every(o=>t.has(o)),V=(t,o)=>t.find(g=>g.roleId===o)?.roleKey??`#${o}`;function be(t,o){return ne(t,o)}function ne(t,o){let g=t;async function b(s,a,p,y,w){if(y.size===0)return;let n=await s.listGroupRoles(p),h=new Set;for(let e of n){if(!y.has(e.roleId)||h.has(e.groupId))continue;h.add(e.groupId);let l=await o.linkLookup.externalGroupKey(p,e.groupId,a);if(l!==null)throw new Error(o.message(e.roleKey||V(w,e.roleId),l))}}return{...t,withTransaction:(s,a)=>g.withTransaction((p,y)=>s(ne(p,o),y),a),async assignGroupRole(s,a,p,y){await g.withTransaction(async(w,n)=>{let h=await w.listGrants(s);if(J(H(h,p,o.adminAppKey,o.adminResourceKey))){let e=await o.linkLookup.externalGroupKey(s,a,n);if(e!==null)throw new Error(o.message(V(h,p),e))}await w.assignGroupRole(s,a,p,y)})},async createGrant(s,a,p){await g.withTransaction(async(y,w)=>{let h=(await y.listResources(s)).find(e=>e.id===a.resourceId);if(h?.appKey===o.adminAppKey&&h?.resourceKey===o.adminResourceKey){let e=await y.listGrants(s),l=H(e,a.roleId,o.adminAppKey,o.adminResourceKey);l.add(a.action),J(l)&&await b(y,w,s,new Set([a.roleId]),e)}await y.createGrant(s,a,p)})}}}async function we(t,o,g,b){let s=(await t.listGroupRoles(o)).filter(p=>p.groupId===g);if(s.length===0)return;let a=await t.listGrants(o);for(let p of s)if(J(H(a,p.roleId,b.adminAppKey,b.adminResourceKey)))throw new Error(b.message(p.roleKey||V(a,p.roleId),p.groupKey))}var $=require("drizzle-orm");async function z(t,o,g){let{ledger:b,group:s}=o,{tenantId:a,externalUserId:p,email:y}=g;if(p===null&&y==="")return[];let w={ledgerId:b.id,groupId:b.groupId,tenantId:s.tenantId,externalUserId:b.externalUserId},n=async d=>(await t.select(w).from(b).innerJoin(s,(0,$.and)((0,$.eq)(s.id,b.groupId),(0,$.eq)(s.tenantId,a),(0,$.eq)(s.isActive,!0))).where(d)).map(I=>({ledgerId:Number(I.ledgerId),groupId:Number(I.groupId),tenantId:String(I.tenantId),externalUserId:I.externalUserId===null?null:String(I.externalUserId)})),h=d=>{let v=new Map;for(let I of d)v.set(I.ledgerId,{ledgerId:I.ledgerId,groupId:I.groupId,tenantId:I.tenantId});return[...v.values()].sort((I,T)=>I.ledgerId-T.ledgerId)},e=p===null?[]:await n((0,$.eq)(b.externalUserId,p));if(y==="")return h(e);let l=await n((0,$.eq)(b.email,y)),A=d=>p!==null&&d.externalUserId!==null&&d.externalUserId!==p;return h([...e,...l.filter(d=>!A(d))])}var O=require("@aiquants/auth-core"),oe=require("@aiquants/auth-directory-core"),x=require("@aiquants/authz-core"),u=require("drizzle-orm");var W=["direct","transitive"];function K(t){if(!W.includes(t))throw new TypeError(`[@aiquants/auth-directory-drizzle] membershipMode must be one of ${W.join(" | ")}, received ${JSON.stringify(t)}`);return t}function fe(t,o,g,b){let s=t,a=b.ensureConnection??(async()=>{}),p=b.policyCacheTtlMs??0;if(!Number.isFinite(p)||p<0)throw new TypeError(`[@aiquants/auth-directory-drizzle] policyCacheTtlMs must be a non-negative number, received ${String(b.policyCacheTtlMs)}`);let y=new Map,w=r=>y.delete(r),{TDGroupExternalLink:n,TDGroupMemberEmail:h,TDTenantMembershipGroup:e,TDAllowlistGroup:l,TDDirectorySyncRequest:A}=o,{TMGroup:d,TDGroupMember:v}=g;async function I(r,i,m){if((await r.select({groupId:e.groupId}).from(e).where((0,u.and)((0,u.eq)(e.tenantId,i),(0,u.eq)(e.groupId,m),(0,u.eq)(e.isBreakGlass,!0)))).length>0)throw new Error(`Group ${m} is a break-glass proof group; a break-glass proof path must be one the synchronization can never touch.`)}async function T(r,i,m){let[f]=await r.select({id:d.id}).from(d).where((0,u.and)((0,u.eq)(d.id,m),(0,u.eq)(d.tenantId,i)));if(!f)throw new Error(`Group not found in tenant: ${m}`)}function G(r,i){return{linkId:Number(r.linkId),groupId:Number(r.groupId),tenantId:String(r.tenantId),provider:String(r.provider),externalId:String(r.externalId),externalKey:String(r.externalKey),membershipMode:K(String(r.membershipMode)),isSyncEnabled:!!r.isSyncEnabled,...r.syncedAt?{syncedAt:new Date(r.syncedAt).toISOString()}:{},...r.syncError?{syncError:String(r.syncError)}:{},unresolvedCount:i}}async function _(r,i){let m=await r.select({groupId:h.groupId,n:(0,u.count)()}).from(h).innerJoin(d,(0,u.and)((0,u.eq)(d.id,h.groupId),(0,u.eq)(d.tenantId,i))).where((0,u.isNull)(h.resolvedUserId)).groupBy(h.groupId);return new Map(m.map(f=>[Number(f.groupId),Number(f.n)]))}return{async listLinks(r){(0,x.assertTenantId)(r,"listLinks(tenantId)"),await a();let i=await s.select({linkId:n.id,groupId:n.groupId,tenantId:n.tenantId,provider:n.provider,externalId:n.externalId,externalKey:n.externalKey,membershipMode:n.membershipMode,isSyncEnabled:n.isSyncEnabled,syncedAt:n.syncedAt,syncError:n.syncError}).from(n).where((0,u.eq)(n.tenantId,r)).orderBy((0,u.asc)(n.groupId)),m=await _(s,r);return i.map(f=>((0,x.assertTenantMatch)(r,String(f.tenantId),"listLinks(row.tenantId)"),G(f,m.get(Number(f.groupId))??0)))},async externalGroupKey(r,i,m){(0,x.assertTenantId)(r,"externalGroupKey(tenantId)"),await a();let[f]=await(m??s).select({externalKey:n.externalKey}).from(n).where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)));return f?String(f.externalKey):null},async linkGroup(r,i,m,f){(0,x.assertTenantId)(r,"linkGroup(tenantId)");let D=K(m.membershipMode),k=m.externalId.trim(),E=(0,O.normalizeAuthEmail)(m.externalKey);if(k===""||E==="")throw new TypeError("[@aiquants/auth-directory-drizzle] externalId and externalKey must be non-empty");await a(),await b.linkable.assertLinkableAndWrite(r,i,async j=>{let M=j;await T(M,r,i),await I(M,r,i),await M.insert(n).output().values({groupId:i,tenantId:r,provider:m.provider,externalId:k,externalKey:E,membershipMode:D,isSyncEnabled:!0,vanishedObservations:0,createdAt:new Date,createdBy:f})}),w(r)},async unlinkGroup(r,i){(0,x.assertTenantId)(r,"unlinkGroup(tenantId)"),await a(),await s.transaction(async m=>{await T(m,r,i),await m.delete(h).where((0,u.eq)(h.groupId,i)),await m.delete(l).where((0,u.and)((0,u.eq)(l.groupId,i),(0,u.eq)(l.tenantId,r))),await m.delete(n).where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)))}),w(r)},async setSyncEnabled(r,i,m,f){(0,x.assertTenantId)(r,"setSyncEnabled(tenantId)"),await a(),await s.update(n).set({isSyncEnabled:m,updatedAt:new Date,updatedBy:f}).output().where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)))},async requestSync(r,i,m){(0,x.assertTenantId)(r,"requestSync(tenantId)"),await a(),await s.transaction(async f=>{i!==null&&await T(f,r,i),await f.insert(A).output().values({tenantId:r,groupId:i,requestedBy:m,requestedAt:new Date,createdAt:new Date,createdBy:m})})},async getStatus(r){(0,x.assertTenantId)(r,"getStatus(tenantId)"),await a();let i=await s.select({groupId:n.groupId,isSyncEnabled:n.isSyncEnabled,syncedAt:n.syncedAt,syncError:n.syncError}).from(n).where((0,u.eq)(n.tenantId,r)),[m]=await s.select({n:(0,u.count)()}).from(A).where((0,u.and)((0,u.eq)(A.tenantId,r),(0,u.isNull)(A.finishedAt))),f=i.filter(M=>!!M.isSyncEnabled),D=f.map(M=>M.syncedAt?new Date(M.syncedAt).getTime():null),k=D.length>0&&D.every(M=>M!==null)?Math.min(...D):null,j=i.length>0&&f.length===0||f.length>0&&(k===null||Date.now()-k>b.stalenessThresholdSec*1e3);return{isEnabled:b.isEnabled,linkedGroupCount:i.length,...k!==null?{oldestSyncedAt:new Date(k).toISOString()}:{},isStale:j,pausedGroupCount:i.length-f.length,stalenessThresholdSec:b.stalenessThresholdSec,erroredGroupIds:i.filter(M=>!!M.syncError).map(M=>Number(M.groupId)).sort((M,ue)=>M-ue),pendingRequestCount:Number(m?.n??0)}},async loadTenantMembershipPolicy(r){(0,x.assertTenantId)(r,"loadTenantMembershipPolicy(tenantId)");let i=p>0?y.get(r):void 0;if(i&&Date.now()-i.loadedAt<p)return i.policy;await a();let m=await s.select({groupId:e.groupId,isBreakGlass:e.isBreakGlass,externalLinkId:n.id}).from(e).innerJoin(d,(0,u.and)((0,u.eq)(d.id,e.groupId),(0,u.eq)(d.tenantId,r))).leftJoin(n,(0,u.eq)(n.groupId,e.groupId)).where((0,u.eq)(e.tenantId,r));if(m.length===0){let E={kind:"no-proof-required"};return p>0&&y.set(r,{policy:E,loadedAt:Date.now()}),E}let f=m.map(E=>Number(E.groupId)),D=m.filter(E=>!!E.isBreakGlass);for(let E of D)if(E.externalLinkId!==null)throw new Error(`Break-glass group ${Number(E.groupId)} is externally sourced; a break-glass proof path must be one the synchronization can never touch.`);let k={kind:"require-proof",proofGroupIds:f,breakGlassGroupIds:D.map(E=>Number(E.groupId))};return(0,oe.assertTenantMembershipPolicy)(k,`tenant ${r}`),p>0&&y.set(r,{policy:k,loadedAt:Date.now()}),k},async setTenantMembershipGroup(r,i,m,f){(0,x.assertTenantId)(r,"setTenantMembershipGroup(tenantId)"),await a(),await s.transaction(async D=>{if(await T(D,r,i),m){let[E]=await D.select({id:n.id}).from(n).where((0,u.and)((0,u.eq)(n.tenantId,r),(0,u.eq)(n.groupId,i)));if(E)throw new Error(`Group ${i} is externally sourced; a break-glass proof path must be one the synchronization can never touch.`)}if((await D.select({groupId:e.groupId}).from(e).where((0,u.and)((0,u.eq)(e.tenantId,r),(0,u.eq)(e.groupId,i)))).length>0){await D.update(e).set({isBreakGlass:m,updatedAt:new Date,updatedBy:f}).output().where((0,u.and)((0,u.eq)(e.tenantId,r),(0,u.eq)(e.groupId,i))),w(r);return}await D.insert(e).output().values({tenantId:r,groupId:i,isBreakGlass:m,createdAt:new Date,createdBy:f})}),w(r)},async removeTenantMembershipGroup(r,i){(0,x.assertTenantId)(r,"removeTenantMembershipGroup(tenantId)"),await a(),await s.transaction(async m=>{let D=(await m.select({groupId:e.groupId,isBreakGlass:e.isBreakGlass}).from(e).where((0,u.eq)(e.tenantId,r))).filter(k=>Number(k.groupId)!==i);if(D.length>0&&!D.some(k=>!!k.isBreakGlass))throw new Error(`Removing group ${i} would leave tenant ${r} with a membership proof but no break-glass path.`);await m.delete(e).where((0,u.and)((0,u.eq)(e.tenantId,r),(0,u.eq)(e.groupId,i)))}),w(r)},async setGroupActive(r,i,m,f){(0,x.assertTenantId)(r,"setGroupActive(tenantId)"),await a(),await s.update(d).set({isActive:m,updatedAt:new Date,updatedBy:f}).output().where((0,u.and)((0,u.eq)(d.id,i),(0,u.eq)(d.tenantId,r)))},async listLedgerGroupIds(r,i){if((0,x.assertTenantId)(r,"listLedgerGroupIds(tenantId)"),!b.isEnabled)return[];await a();let m=await z(s,{ledger:h,group:d},{tenantId:r,externalUserId:i.externalUserId?.trim()||null,email:(0,O.normalizeAuthEmail)(i.email)});return[...new Set(m.map(f=>f.groupId))].sort((f,D)=>f-D)},async isEmailAllowedByGroup(r){if(!b.isEnabled)return!1;let i=(0,O.normalizeAuthEmail)(r);if(i==="")return!1;await a();let[m]=await s.select({id:h.id}).from(h).innerJoin(l,(0,u.eq)(l.groupId,h.groupId)).innerJoin(d,(0,u.and)((0,u.eq)(d.id,h.groupId),(0,u.eq)(d.isActive,!0))).where((0,u.eq)(h.email,i));return!!m},async listAllowlistGroups(r){return(0,x.assertTenantId)(r,"listAllowlistGroups(tenantId)"),await a(),(await s.select({id:l.id,groupId:l.groupId,groupKey:d.groupKey,groupName:d.name,description:l.description}).from(l).innerJoin(d,(0,u.and)((0,u.eq)(d.id,l.groupId),(0,u.eq)(d.tenantId,r))).where((0,u.eq)(l.tenantId,r)).orderBy((0,u.asc)(d.name))).map(m=>({id:Number(m.id),type:"group",groupId:Number(m.groupId),groupKey:String(m.groupKey),groupName:String(m.groupName),...m.description?{description:String(m.description)}:{},owner:{kind:"tenant",tenantId:r},readOnly:!1}))},async addAllowlistGroup(r,i,m,f){(0,x.assertTenantId)(r,"addAllowlistGroup(tenantId)"),await a(),await s.transaction(async D=>{await T(D,r,i);let[k]=await D.select({id:n.id}).from(n).where((0,u.and)((0,u.eq)(n.groupId,i),(0,u.eq)(n.tenantId,r)));if(!k)throw new Error(`Group ${i} is locally managed; only externally-sourced groups can gate sign-in, because the decision reads the upstream member ledger.`);await D.insert(l).output().values({tenantId:r,groupId:i,description:m??null,createdAt:new Date,createdBy:f})})},async removeAllowlistGroup(r,i){(0,x.assertTenantId)(r,"removeAllowlistGroup(tenantId)"),await a(),await s.delete(l).where((0,u.and)((0,u.eq)(l.id,i),(0,u.eq)(l.tenantId,r)))},async countProjectedMembers(r,i){(0,x.assertTenantId)(r,"countProjectedMembers(tenantId)"),await a();let[m]=await s.select({n:(0,u.count)()}).from(v).innerJoin(d,(0,u.and)((0,u.eq)(d.id,v.groupId),(0,u.eq)(d.tenantId,r))).where((0,u.eq)(v.groupId,i));return Number(m?.n??0)}}}var ie=require("@aiquants/auth-core"),B=require("@aiquants/authz-core");async function Ie(t,o){let g=(0,B.assertTenantId)(o.tenantId,"promoteLedgerForUser(tenantId)");if(!Number.isInteger(o.userId)||o.userId<=0)throw new TypeError(`[@aiquants/auth-directory-drizzle] userId must be a positive integer, received ${String(o.userId)}`);let b=(0,ie.normalizeAuthEmail)(o.email),s=o.externalUserId?.trim()||null;if(s===null&&b==="")return{addedGroupIds:[],matchedLedgerIds:[]};let a=await t.findLedgerMatches({tenantId:g,externalUserId:s,email:b});if(a.length===0)return{addedGroupIds:[],matchedLedgerIds:[]};for(let n of a)(0,B.assertTenantMatch)(g,n.tenantId,"promoteLedgerForUser(findLedgerMatches row)");let p=[...new Set(a.map(n=>n.ledgerId))].sort((n,h)=>n-h),y=[...new Set(a.map(n=>n.groupId))].sort((n,h)=>n-h);return{addedGroupIds:[...await t.attachUserToGroups({tenantId:g,userId:o.userId,ledgerIds:p,groupIds:y})].sort((n,h)=>n-h),matchedLedgerIds:p}}var Y=require("@aiquants/authz-core"),R=require("drizzle-orm");var se=2100;var qe=500;function L(t,o=500){if(!Number.isInteger(o)||o<=0)throw new TypeError(`[@aiquants/auth-directory-drizzle] chunk size must be a positive integer, received ${String(o)}`);let g=[];for(let b=0;b<t.length;b+=o)g.push(t.slice(b,b+o));return g}function N(t,o,g=100){if(!Number.isInteger(o)||o<=0)throw new TypeError(`[@aiquants/auth-directory-drizzle] parametersPerItem must be a positive integer, received ${String(o)}`);if(!Number.isInteger(g)||g<0)throw new TypeError(`[@aiquants/auth-directory-drizzle] reservedParameters must be a non-negative integer, received ${String(g)}`);let b=2100-g,s=Math.floor(b/o);if(s<1)throw new TypeError(`[@aiquants/auth-directory-drizzle] a single item binds ${o} parameters, which exceeds the ${b} available in one statement`);return L(t,s)}var Ae=4,Se=100;function ve(t,o,g,b){let s=t,a=b.ensureConnection??(async()=>{}),p=b.now??(()=>new Date),y=o.TDGroupMemberEmail,{TMGroup:w,TDGroupMember:n}=g;return{async findLedgerMatches(h){return(0,Y.assertTenantId)(h.tenantId,"findLedgerMatches(tenantId)"),await a(),z(s,{ledger:y,group:w},h)},async attachUserToGroups({tenantId:h,userId:e,ledgerIds:l,groupIds:A}){return(0,Y.assertTenantId)(h,"attachUserToGroups(tenantId)"),await a(),l.length===0?[]:s.transaction(async d=>{let v=new Set;for(let r of L(A)){let i=await d.select({id:w.id}).from(w).where((0,R.and)((0,R.inArray)(w.id,r),(0,R.eq)(w.tenantId,h),(0,R.eq)(w.isActive,!0)));for(let m of i)v.add(Number(m.id))}let I=A.filter(r=>v.has(r));if(I.length===0)return[];let T=new Set;for(let r of L(I)){let i=await d.select({groupId:n.groupId}).from(n).where((0,R.and)((0,R.eq)(n.userId,e),(0,R.inArray)(n.groupId,r)));for(let m of i)T.add(Number(m.groupId))}let G=I.filter(r=>!T.has(r)),_=Math.max(1,2100-Se-I.length);for(let r of L(l,_))await d.update(y).set({resolvedUserId:e}).output().where((0,R.and)((0,R.inArray)(y.id,r),(0,R.inArray)(y.groupId,I)));if(G.length>0){let r=p();for(let i of N(G,Ae))await d.insert(n).output().values(i.map(m=>({groupId:m,userId:e,createdAt:r,createdBy:b.actor})))}return G})}}}var U=require("@aiquants/authz-drizzle"),c=require("drizzle-orm/mssql-core"),ae="provider",Te=["TDGroupExternalLink","TDTenantMembershipGroup","TDAllowlistGroup","TDDirectorySyncRequest","TMAllowlist"];function De(t,o){let g=(0,c.mssqlSchema)(t),b=()=>({createdAt:(0,c.datetime2)("created_at"),createdBy:(0,c.nvarchar)("created_by",{length:50}),updatedAt:(0,c.datetime2)("updated_at"),updatedBy:(0,c.nvarchar)("updated_by",{length:50})}),s=()=>({createdAt:(0,c.datetime2)("created_at"),createdBy:(0,c.nvarchar)("created_by",{length:50})}),a=g.table("TDGroupExternalLink",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),provider:(0,c.nvarchar)(ae,{length:32}).notNull(),externalId:(0,c.nvarchar)("external_id",{length:256}).notNull(),externalKey:(0,c.nvarchar)("external_key",{length:320}).notNull(),membershipMode:(0,c.nvarchar)("membership_mode",{length:16}).notNull(),isSyncEnabled:(0,c.bit)("is_sync_enabled").notNull(),syncedAt:(0,c.datetime2)("synced_at"),syncError:(0,c.nvarchar)("sync_error",{length:1e3}),vanishedObservations:(0,c.int)("vanished_observations").notNull(),...b()},e=>[(0,c.primaryKey)({name:`${t}_TDGroupExternalLink_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TDGroupExternalLink_group_uq`).on(e.groupId),(0,c.uniqueIndex)(`${t}_TDGroupExternalLink_external_uq`).on(e.tenantId,e.provider,e.externalId),(0,c.foreignKey)({name:`${t}_TDGroupExternalLink_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),p=g.table("TDGroupMemberEmail",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),email:(0,c.nvarchar)("email",{length:320}).notNull(),externalUserId:(0,c.nvarchar)("external_user_id",{length:128}),resolvedUserId:(0,c.bigint)("resolved_user_id",{mode:"number"}),observedAt:(0,c.datetime2)("observed_at").notNull(),...b()},e=>[(0,c.primaryKey)({name:`${t}_TDGroupMemberEmail_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TDGroupMemberEmail_group_email_uq`).on(e.groupId,e.email),(0,c.foreignKey)({name:`${t}_TDGroupMemberEmail_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),y=g.table("TDTenantMembershipGroup",{tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),isBreakGlass:(0,c.bit)("is_break_glass").notNull(),...s()},e=>[(0,c.primaryKey)({name:`${t}_TDTenantMembershipGroup_pk`,columns:[e.tenantId,e.groupId]}),(0,c.foreignKey)({name:`${t}_TDTenantMembershipGroup_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),w=g.table("TDAllowlistGroup",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}).notNull(),description:(0,c.nvarchar)("description",{length:512}),...s()},e=>[(0,c.primaryKey)({name:`${t}_TDAllowlistGroup_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TDAllowlistGroup_tenant_group_uq`).on(e.tenantId,e.groupId),(0,c.foreignKey)({name:`${t}_TDAllowlistGroup_group_id_fk`,columns:[e.groupId],foreignColumns:[o.groupTable.id]})]),n=g.table("TDDirectorySyncRequest",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),groupId:(0,c.bigint)("group_id",{mode:"number"}),requestedBy:(0,c.nvarchar)("requested_by",{length:320}).notNull(),requestedAt:(0,c.datetime2)("requested_at").notNull(),pickedAt:(0,c.datetime2)("picked_at"),finishedAt:(0,c.datetime2)("finished_at"),result:(0,c.nvarchar)("result",{length:32}),error:(0,c.nvarchar)("error",{length:2e3}),...s()},e=>[(0,c.primaryKey)({name:`${t}_TDDirectorySyncRequest_pk`,columns:[e.id]})]),h=g.table("TMAllowlist",{id:(0,c.bigint)("id",{mode:"number"}).identity().notNull(),tenantId:(0,c.nvarchar)(U.AUTHZ_TENANT_COLUMN,{length:64}).notNull(),pattern:(0,c.nvarchar)("pattern",{length:256}).notNull(),type:(0,c.nvarchar)("type",{length:32}).notNull(),description:(0,c.nvarchar)("description",{length:512}),...s()},e=>[(0,c.primaryKey)({name:`${t}_TMAllowlist_pk`,columns:[e.id]}),(0,c.uniqueIndex)(`${t}_TMAllowlist_pattern_uq`).on(e.tenantId,e.pattern)]);return{TDGroupExternalLink:a,TDGroupMemberEmail:p,TDTenantMembershipGroup:y,TDAllowlistGroup:w,TDDirectorySyncRequest:n,TMAllowlist:h}}var C=require("@aiquants/auth-directory-core");var X=(t,o=20)=>t.length<=o?t.join(", "):`${t.slice(0,o).join(", ")} \u307B\u304B ${t.length-o} \u4EF6`,Q={upstreamUnreadable:t=>`\u4E0A\u6D41\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u8AAD\u307F\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${t}`,localWriteFailed:t=>`\u30ED\u30FC\u30AB\u30EB\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${t}`,resolverIncomplete:(t,o)=>`\u4E0A\u6D41\u304C ${t} \u4EF6\u306E\u30E1\u30F3\u30D0\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F\u304C\u3001\u7A81\u5408\u7D50\u679C\u306F ${o} \u4EF6\u3067\u3057\u305F\u3002\u4EF6\u6570\u304C\u6E1B\u308B\u7A81\u5408\u306F\u3001\u89E3\u6C7A\u3067\u304D\u306A\u304B\u3063\u305F\u4EBA\u7269\u3092\u300C\u4E0A\u6D41\u304B\u3089\u6D88\u3048\u305F\u300D\u3068\u3057\u3066\u524A\u9664\u3057\u3066\u3057\u307E\u3046\u305F\u3081\u4E2D\u65AD\u3057\u307E\u3057\u305F\u3002\u89E3\u6C7A\u3067\u304D\u306A\u3044\u30E1\u30F3\u30D0\u30FC\u306F\u7701\u7565\u305B\u305A resolvedUserId: null \u3067\u8FD4\u3059\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002`,groupMissing:(t,o,g)=>`\u4E0A\u6D41\u3067\u30B0\u30EB\u30FC\u30D7\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t})\u3002\u9023\u7D9A ${o} \u56DE\u76EE\u3067\u3059\u3002${g} \u56DE\u306B\u9054\u3057\u305F\u6642\u70B9\u3067\u30B0\u30EB\u30FC\u30D7\u3092\u7121\u52B9\u5316\u3057\u307E\u3059\u3002`,groupVanished:(t,o)=>`\u4E0A\u6D41\u3067\u30B0\u30EB\u30FC\u30D7\u304C ${o} \u56DE\u9023\u7D9A\u3067\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F (${t})\u3002\u30B0\u30EB\u30FC\u30D7\u3092\u7121\u52B9\u5316\u3057\u307E\u3057\u305F\u3002\u4E0A\u6D41\u304C\u5FA9\u65E7\u3059\u308C\u3070\u6B21\u56DE\u306E\u540C\u671F\u3067\u81EA\u52D5\u7684\u306B\u518D\u6709\u52B9\u5316\u3055\u308C\u307E\u3059\u3002`,planRefused:t=>{if(t.reason==="invalid-upstream-data")return`\u540C\u671F\u3092\u4E2D\u65AD\u3057\u307E\u3057\u305F: \u4E0A\u6D41\u306E\u30E1\u30F3\u30D0\u30FC\u4E00\u89A7\u306B\u6271\u3048\u306A\u3044\u30A2\u30C9\u30EC\u30B9\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059 (${X(t.offendingEmails)})\u3002`;let o=t.axis==="membership"?"\u6A29\u9650\u3092\u5931\u3046\u4EBA\u6570":"\u30B5\u30A4\u30F3\u30A4\u30F3\u3067\u304D\u306A\u304F\u306A\u308B\u4EBA\u6570",g=t.axis==="membership"?t.withheldProjectionRemoves.map(String):t.withheldLedgerDeletes;return[`\u540C\u671F\u3092\u4E2D\u65AD\u3057\u307E\u3057\u305F: ${o}\u304C ${t.population} \u4EBA\u4E2D ${t.removalCount} \u4EBA\u306B\u306A\u308A\u307E\u3059`,`(\u4E0A\u9650: ${t.limits.maxRemovalCount} \u4EF6 / \u6BD4\u7387 ${t.limits.maxRemovalRatio})\u3002`,`\u5DEE\u3057\u6B62\u3081\u305F\u5BFE\u8C61: ${X(g)}\u3002`,"\u4E0A\u6D41\u5074\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u610F\u56F3\u3057\u305F\u5909\u66F4\u3067\u3042\u308C\u3070\u3001\u3053\u306E\u8EF8\u306E\u4E0A\u9650\u3060\u3051\u3092\u4E00\u6642\u7684\u306B\u5F15\u304D\u4E0A\u3052\u3066\u518D\u5B9F\u884C\u3057\u307E\u3059\u3002"].join(" ")},removalsRefused:t=>`${t.length} \u4EF6\u306E\u6240\u5C5E\u89E3\u9664\u304C\u6700\u5F8C\u306E\u7BA1\u7406\u8005\u30AC\u30FC\u30C9\u306B\u3088\u308A\u62D2\u5426\u3055\u308C\u307E\u3057\u305F (\u30E6\u30FC\u30B6\u30FC ${X(t.map(o=>String(o.userId)))})\u3002\u6B8B\u308A\u306E\u5909\u66F4\u306F\u9069\u7528\u6E08\u307F\u3067\u3059\u3002`,foreignProvider:(t,o)=>`\u3053\u306E\u30EA\u30F3\u30AF\u306E\u4F9B\u7D66\u5143\u306F ${t} \u3067\u3059\u304C\u3001\u5B9F\u884C\u4E2D\u306E\u540C\u671F\u306F ${o} \u7528\u3067\u3059\u3002\u5BFE\u5FDC\u3059\u308B\u540C\u671F\u30B8\u30E7\u30D6\u304B\u3089\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`};var Z=["aborted","missing","vanished","upstream-failed","local-failed","foreign-provider"];function xe(t){let{directory:o,repository:g,policy:b,now:s,logger:a}=t,p=t.messages??Q;if((0,C.assertBlastRadiusPolicy)(b),!Number.isInteger(t.vanishedThreshold)||t.vanishedThreshold<1)throw new TypeError(`[@aiquants/auth-directory-drizzle] vanishedThreshold must be a positive integer, received ${String(t.vanishedThreshold)}`);if(typeof t.provider!="string"||t.provider.trim()==="")throw new TypeError("[@aiquants/auth-directory-drizzle] provider must be a non-empty string so links of other providers can be told apart");async function y(e,l){try{await g.recordFailure(e,l)}catch(A){a.error(`[auth-directory] could not record the failure for ${e.externalKey}:`,A)}}async function w(e){try{let l=await o.getGroup(e.externalId);return l===null?{kind:"missing"}:{kind:"ok",group:l,members:await o.listGroupMembers(l,e.membershipMode)}}catch(l){return{kind:"failed",error:l instanceof Error?l:new Error(String(l))}}}async function n(e){let l=await g.recordVanishedObservation(e,p.groupMissing(e.externalKey,e.vanishedObservations+1,t.vanishedThreshold));return l<t.vanishedThreshold?(a.warn(`[auth-directory] ${e.externalKey} missing upstream (${l}/${t.vanishedThreshold})`),{kind:"missing",link:e,observations:l}):(await g.markGroupInactive(e),await y(e,p.groupVanished(e.externalKey,l)),a.warn(`[auth-directory] ${e.externalKey} deactivated after ${l} consecutive absences`),{kind:"vanished",link:e})}async function h(e){if(e.provider!==t.provider)return await y(e,p.foreignProvider(e.provider,t.provider)),a.warn(`[auth-directory] skipping ${e.externalKey}: belongs to provider ${e.provider}`),{kind:"foreign-provider",link:e};let l=await w(e);if(l.kind==="missing")return n(e);if(l.kind==="failed")return await y(e,p.upstreamUnreadable(l.error.message)),a.error(`[auth-directory] upstream read failed for ${e.externalKey}:`,l.error),{kind:"upstream-failed",link:e,error:l.error};try{let[A,d]=await Promise.all([g.loadGroupSnapshot(e),g.resolveMembers(l.members)]);if(d.length!==l.members.length){let _=p.resolverIncomplete(l.members.length,d.length);return await y(e,_),a.error(`[auth-directory] ${_}`),{kind:"local-failed",link:e,error:new Error(_)}}let v=(0,C.reconcile)(A,d,b);if(v.aborted)return await y(e,p.planRefused(v.aborted)),a.warn(`[auth-directory] plan refused for ${e.externalKey}: ${v.aborted.reason}`),{kind:"aborted",link:e,plan:v};let I=v.ledgerUpserts.length>0||v.ledgerDeletes.length>0||v.projectionAdds.length>0||v.projectionRemoves.length>0,T=s(),G={refusals:[]};return I&&(G=await g.applyPlan(e,v,T)),await g.recordSuccess(e,l.group,T),G.refusals.length>0&&(await y(e,p.removalsRefused(G.refusals)),a.warn(`[auth-directory] ${G.refusals.length} removal(s) refused for ${e.externalKey}`)),v.unresolvedEmails.length>0&&a.info(`[auth-directory] ${e.externalKey}: ${v.unresolvedEmails.length} upstream member(s) have no local user yet`),I?{kind:"applied",link:e,plan:v}:{kind:"unchanged",link:e}}catch(A){let d=A instanceof Error?A:new Error(String(A));return await y(e,p.localWriteFailed(d.message)),a.error(`[auth-directory] local write failed for ${e.externalKey}:`,d),{kind:"local-failed",link:e,error:d}}}return{syncOne:h,async run(e={}){let l=await g.listSyncableLinks(e),A=[];for(let v of l)try{A.push(await h(v))}catch(I){let T=I instanceof Error?I:new Error(String(I));a.error(`[auth-directory] ${v.externalKey} ended abnormally:`,T),A.push({kind:"local-failed",link:v,error:T})}let d=A.filter(v=>Z.includes(v.kind)).length;return a.info(`[auth-directory] run finished: ${A.length} link(s), ${d} unhealthy`),{outcomes:A,unhealthyCount:d}}}}var de=require("@aiquants/authz-core"),P=require("drizzle-orm"),ee=2e3;function ke(t,o,g){let b=t,s=g.ensureConnection??(async()=>{}),a=o.TDDirectorySyncRequest,p=g.maxErrorLength??ee;if(!Number.isInteger(p)||p<1||p>ee)throw new TypeError(`[@aiquants/auth-directory-drizzle] maxErrorLength must be an integer within 1..${ee}, received ${String(g.maxErrorLength)}`);return{async claim(){await s();let y=await b.select({id:a.id}).from(a).where((0,P.isNull)(a.pickedAt)).orderBy((0,P.asc)(a.id));for(let w of y){let h=(await b.update(a).set({pickedAt:g.now()}).output().where((0,P.and)((0,P.eq)(a.id,Number(w.id)),(0,P.isNull)(a.pickedAt))))?.[0];if(!h)continue;let e=String(h.tenant_id??h.tenantId??""),l=h.group_id??h.groupId??null;return{id:Number(h.id),tenantId:(0,de.assertTenantId)(e,"claim(row.tenantId)"),groupId:l===null?null:Number(l),requestedBy:String(h.requested_by??h.requestedBy??"")}}return null},async finish(y,w){await s();let n=w.error?w.error.slice(0,p):null;await b.update(a).set({finishedAt:g.now(),result:w.result,error:n}).output().where((0,P.eq)(a.id,y))},async listStranded(y){return await s(),(await b.select({id:a.id,pickedAt:a.pickedAt}).from(a).where((0,P.isNull)(a.finishedAt)).orderBy((0,P.asc)(a.id))).filter(n=>n.pickedAt!==null&&new Date(n.pickedAt)<y).map(n=>Number(n.id))}}}var re=require("@aiquants/auth-core"),q=require("@aiquants/authz-core"),S=require("drizzle-orm");var Ge=7,Ee=4;function Me(t,o,g,b){let s=t,a=b.ensureConnection??(async()=>{}),{TDGroupExternalLink:p,TDGroupMemberEmail:y}=o,{TMGroup:w,TDGroupMember:n}=g,h=b.actor;return{async listSyncableLinks(e){await a();let l=[(0,S.eq)(p.isSyncEnabled,!0)];return e.tenantId!==void 0&&l.push((0,S.eq)(p.tenantId,(0,q.assertTenantId)(e.tenantId,"listSyncableLinks(tenantId)"))),e.groupId!==void 0&&l.push((0,S.eq)(p.groupId,e.groupId)),(await s.select({linkId:p.id,groupId:p.groupId,linkTenantId:p.tenantId,groupTenantId:w.tenantId,groupKey:w.groupKey,isGroupActive:w.isActive,provider:p.provider,externalId:p.externalId,externalKey:p.externalKey,membershipMode:p.membershipMode,vanishedObservations:p.vanishedObservations}).from(p).innerJoin(w,(0,S.eq)(w.id,p.groupId)).where((0,S.and)(...l))).map(d=>((0,q.assertTenantMatch)(String(d.groupTenantId),String(d.linkTenantId),"listSyncableLinks(link.tenantId vs TMGroup.tenant_id)"),{linkId:Number(d.linkId),groupId:Number(d.groupId),groupKey:String(d.groupKey),tenantId:String(d.groupTenantId),provider:String(d.provider),externalId:String(d.externalId),externalKey:String(d.externalKey),membershipMode:K(String(d.membershipMode)),isGroupActive:!!d.isGroupActive,vanishedObservations:Number(d.vanishedObservations??0)}))},async loadGroupSnapshot(e){await a();let[l,A]=await Promise.all([s.select({email:y.email,externalUserId:y.externalUserId,resolvedUserId:y.resolvedUserId}).from(y).where((0,S.eq)(y.groupId,e.groupId)),s.select({userId:n.userId}).from(n).where((0,S.eq)(n.groupId,e.groupId))]);return{ledger:l.map(d=>({email:String(d.email),...d.externalUserId?{externalUserId:String(d.externalUserId)}:{},resolvedUserId:d.resolvedUserId===null?null:Number(d.resolvedUserId)})),projectedUserIds:A.map(d=>Number(d.userId))}},resolveMembers(e){return b.memberResolver.resolve(e)},async applyPlan(e,l,A){(0,q.assertTenantId)(e.tenantId,"applyPlan(link.tenantId)"),await a(),(l.ledgerUpserts.length>0||l.projectionAdds.length>0)&&await s.transaction(async I=>{let T=l.ledgerUpserts.map(r=>({...r,email:(0,re.normalizeAuthEmail)(r.email)})),G=new Map;for(let r of L(T.map(i=>i.email))){let i=await I.select({id:y.id,email:y.email}).from(y).where((0,S.and)((0,S.eq)(y.groupId,e.groupId),(0,S.inArray)(y.email,r)));for(let m of i)G.set(String(m.email),Number(m.id))}let _=T.filter(r=>!G.has(r.email));for(let r of N(_,Ge))await I.insert(y).output().values(r.map(i=>({groupId:e.groupId,email:i.email,externalUserId:i.externalUserId??null,resolvedUserId:i.resolvedUserId,observedAt:A,createdAt:A,createdBy:h})));for(let r of T){let i=G.get(r.email);i!==void 0&&await I.update(y).set({externalUserId:r.externalUserId??null,resolvedUserId:r.resolvedUserId,observedAt:A,updatedAt:A,updatedBy:h}).output().where((0,S.eq)(y.id,i))}for(let r of N(l.projectionAdds,Ee)){let i=new Set((await I.select({userId:n.userId}).from(n).where((0,S.and)((0,S.eq)(n.groupId,e.groupId),(0,S.inArray)(n.userId,r)))).map(f=>Number(f.userId))),m=r.filter(f=>!i.has(f));m.length>0&&await I.insert(n).output().values(m.map(f=>({groupId:e.groupId,userId:f,createdAt:A,createdBy:h})))}});let d=[];for(let I of l.projectionRemoves)try{await b.lockoutGuard.guardedWrite(e.tenantId,{removeGroupMembership:{groupId:e.groupId,userId:I}},"remove-group-member",T=>T.delete(n).where((0,S.and)((0,S.eq)(n.groupId,e.groupId),(0,S.eq)(n.userId,I))))}catch(T){d.push({userId:I,applied:!1,refusal:T instanceof Error?T.message:String(T)})}let v=d.map(I=>I.userId);return l.ledgerDeletes.length>0&&await s.transaction(async I=>{for(let T of L(l.ledgerDeletes)){let G=v.length>0?(0,S.or)((0,S.isNull)(y.resolvedUserId),(0,S.notInArray)(y.resolvedUserId,v)):void 0;await I.delete(y).where((0,S.and)((0,S.eq)(y.groupId,e.groupId),(0,S.inArray)(y.email,T),...G?[G]:[]))}}),{refusals:d}},async recordSuccess(e,l,A){await a(),await s.transaction(async d=>{await d.update(p).set({syncedAt:A,syncError:null,vanishedObservations:0,externalId:l.externalId,externalKey:(0,re.normalizeAuthEmail)(l.externalKey),updatedAt:A,updatedBy:h}).output().where((0,S.eq)(p.id,e.linkId)),e.isGroupActive||await d.update(w).set({isActive:!0,updatedAt:A,updatedBy:h}).output().where((0,S.and)((0,S.eq)(w.id,e.groupId),(0,S.eq)(w.tenantId,e.tenantId)))})},async recordFailure(e,l){await a(),await s.update(p).set({syncError:l.slice(0,1e3),updatedAt:new Date,updatedBy:h}).output().where((0,S.eq)(p.id,e.linkId))},async recordVanishedObservation(e,l){await a();let A=e.vanishedObservations+1;return await s.update(p).set({vanishedObservations:A,syncError:l.slice(0,1e3),updatedAt:new Date,updatedBy:h}).output().where((0,S.eq)(p.id,e.linkId)),A},async markGroupInactive(e){await a(),await s.update(w).set({isActive:!1,updatedAt:new Date,updatedBy:h}).output().where((0,S.and)((0,S.eq)(w.id,e.groupId),(0,S.eq)(w.tenantId,e.tenantId)))}}}0&&(module.exports={AUTH_DIRECTORY_PROVIDER_COLUMN,AUTH_DIRECTORY_TENANT_SCOPED_TABLES,MAX_IN_LIST,MAX_PARAMETERS,MEMBERSHIP_MODES,UNHEALTHY_SYNC_OUTCOMES,assertGroupMayBeLinked,assertMembershipMode,chunk,chunkByParameters,createDirectoryLinkStore,createDirectorySync,createDirectorySyncRepository,createPromotionRepository,createSyncRequestQueue,defaultExternalGroupGuardMessage,defaultSyncMessages,defineAuthDirectorySchema,findLedgerRowsForIdentity,promoteLedgerForUser,withExternalGroupGuards});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|