@selvajs/supabase-provider 0.17.0 → 0.19.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/data/SupabaseComputeServerStore.d.ts.map +1 -1
- package/dist/data/SupabaseComputeServerStore.js +3 -2
- package/dist/data/SupabaseComputeServerStore.js.map +1 -1
- package/dist/data/SupabaseInviteStore.d.ts +1 -0
- package/dist/data/SupabaseInviteStore.d.ts.map +1 -1
- package/dist/data/SupabaseInviteStore.js +29 -1
- package/dist/data/SupabaseInviteStore.js.map +1 -1
- package/dist/data/SupabaseShareLinkStore.d.ts +6 -1
- package/dist/data/SupabaseShareLinkStore.d.ts.map +1 -1
- package/dist/data/SupabaseShareLinkStore.js +43 -0
- package/dist/data/SupabaseShareLinkStore.js.map +1 -1
- package/dist/data/migrationHead.d.ts +1 -1
- package/dist/data/migrationHead.js +1 -1
- package/dist/permissions/SupabasePlatformPermissionStore.d.ts +1 -0
- package/dist/permissions/SupabasePlatformPermissionStore.d.ts.map +1 -1
- package/dist/permissions/SupabasePlatformPermissionStore.js +50 -18
- package/dist/permissions/SupabasePlatformPermissionStore.js.map +1 -1
- package/dist/userProfile/SupabaseUserProfileProvider.js +2 -1
- package/dist/userProfile/SupabaseUserProfileProvider.js.map +1 -1
- package/package.json +3 -3
- package/supabase/migrations/20260529202220_selva_definition_version_schema.sql +1 -2
- package/supabase/migrations/20260817120000_invite_platform_permissions.sql +16 -0
- package/supabase/migrations/20260817140000_share_links_org_roster.sql +42 -0
- package/supabase/migrations/20260817160000_rls_matches_access_rules.sql +175 -0
- package/supabase/migrations/20260817180000_atomic_last_admin_invariant.sql +100 -0
- package/supabase/migrations/20260817200000_atomic_first_admin_claim.sql +72 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseComputeServerStore.d.ts","sourceRoot":"","sources":["../../src/data/SupabaseComputeServerStore.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"SupabaseComputeServerStore.d.ts","sourceRoot":"","sources":["../../src/data/SupabaseComputeServerStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC7B,KAAK,OAAO,EACZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAehD;;;;;;;;;;;;;GAaG;AACH,qBAAa,0BAA2B,YAAW,mBAAmB;IAUpE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAV5B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAGf,OAAO,EAAE,YAAY,EACrB,SAAS,CAAC,EAAE,MAAM,YAAA,EACnC,MAAM,CAAC,EAAE,OAAO;IAKX,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC;IA8CzF;;;;OAIG;IACG,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAYnF,mBAAmB,CACxB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,IAAI,CAAC;IA+BV,cAAc,CACnB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC;IAgCV,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBzF,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BpE;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAkCxB;;;;;OAKG;IACG,aAAa,IAAI,OAAO,CAAC,wBAAwB,CAAC;CA0CxD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isOrgServer, isPlatformServer } from '@selvajs/platform';
|
|
1
|
+
import { isOrgServer, isPlatformServer, scopeConfigToOrg } from '@selvajs/platform';
|
|
2
2
|
import { NoopLogger } from '@selvajs/platform';
|
|
3
3
|
// `node:crypto`-based, so it's a server-only subpath, not the root barrel.
|
|
4
4
|
import { decryptSecret, encryptSecret, isEncryptedSecret } from '@selvajs/platform/computeServer';
|
|
@@ -76,11 +76,12 @@ export class SupabaseComputeServerStore {
|
|
|
76
76
|
if (row.default_server_id)
|
|
77
77
|
orgDefaults[row.org_id] = row.default_server_id;
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
const config = {
|
|
80
80
|
servers,
|
|
81
81
|
defaultServerId: platDefRes.data?.default_server_id ?? undefined,
|
|
82
82
|
orgDefaults
|
|
83
83
|
};
|
|
84
|
+
return opts.scopeToOrgId ? scopeConfigToOrg(config, opts.scopeToOrgId) : config;
|
|
84
85
|
}
|
|
85
86
|
/**
|
|
86
87
|
* The solve path's entry point: one row lookup + one decrypt instead of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseComputeServerStore.js","sourceRoot":"","sources":["../../src/data/SupabaseComputeServerStore.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SupabaseComputeServerStore.js","sourceRoot":"","sources":["../../src/data/SupabaseComputeServerStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,7 @@ export declare class SupabaseInviteStore implements IInviteStore {
|
|
|
17
17
|
listByOrg(ctx: RequestContext, orgId: string, opts?: ListOptions): Promise<Page<Invite>>;
|
|
18
18
|
markAccepted(ctx: RequestContext, id: string, userId: string): Promise<void>;
|
|
19
19
|
revoke(ctx: RequestContext, id: string): Promise<void>;
|
|
20
|
+
revokePendingByEmail(ctx: RequestContext, orgId: string, email: string): Promise<string[]>;
|
|
20
21
|
deleteByOrg(ctx: RequestContext, orgId: string): Promise<void>;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=SupabaseInviteStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseInviteStore.d.ts","sourceRoot":"","sources":["../../src/data/SupabaseInviteStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,MAAM,EACN,cAAc,EACd,WAAW,EACX,IAAI,EACJ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD;;;;;;;GAOG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IAEtD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,YAAY,EACrB,MAAM,GAAE,UAAgC;IAGpD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAa9E,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAcxF,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB5E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBtD,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQpE"}
|
|
1
|
+
{"version":3,"file":"SupabaseInviteStore.d.ts","sourceRoot":"","sources":["../../src/data/SupabaseInviteStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,MAAM,EACN,cAAc,EACd,WAAW,EACX,IAAI,EACJ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD;;;;;;;GAOG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IAEtD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,YAAY,EACrB,MAAM,GAAE,UAAgC;IAGpD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAa9E,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAcxF,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB5E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBtD,oBAAoB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwB1F,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQpE"}
|
|
@@ -2,7 +2,7 @@ import { NoopEventSink, actorFrom } from '@selvajs/platform';
|
|
|
2
2
|
import { mapPostgrestError } from './errors.js';
|
|
3
3
|
import { nextCursorFromRange, toRange } from './pagination.js';
|
|
4
4
|
/** Explicit column list for `invites` — every field `rowToInvite` consumes. */
|
|
5
|
-
const INVITE_COLUMNS = 'id, token_hash, email, org_id, org_role, org_permissions, invited_by, created_at, expires_at, accepted_at, accepted_by_user_id';
|
|
5
|
+
const INVITE_COLUMNS = 'id, token_hash, email, org_id, org_role, org_permissions, platform_permissions, invited_by, created_at, expires_at, accepted_at, accepted_by_user_id';
|
|
6
6
|
/**
|
|
7
7
|
* Invite store. `getByTokenHash` routes through a SECURITY DEFINER RPC so an
|
|
8
8
|
* unauthenticated caller (still validating an invite link) can resolve it
|
|
@@ -102,6 +102,30 @@ export class SupabaseInviteStore {
|
|
|
102
102
|
actorId: actorFrom(ctx)
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
|
+
async revokePendingByEmail(ctx, orgId, email) {
|
|
106
|
+
// Emails are stored lowercase at mint time; normalize the needle too so an
|
|
107
|
+
// offboarding call with the address as the admin typed it still matches.
|
|
108
|
+
const { data, error } = await this.clients
|
|
109
|
+
.forRequest(ctx)
|
|
110
|
+
.from('invites')
|
|
111
|
+
.delete()
|
|
112
|
+
.eq('org_id', orgId)
|
|
113
|
+
.eq('email', email.trim().toLowerCase())
|
|
114
|
+
.is('accepted_at', null)
|
|
115
|
+
.select('id');
|
|
116
|
+
if (error)
|
|
117
|
+
throw mapPostgrestError(error);
|
|
118
|
+
const ids = (data ?? []).map((r) => r.id);
|
|
119
|
+
for (const id of ids) {
|
|
120
|
+
await this.events.emit({
|
|
121
|
+
type: 'invite.revoked',
|
|
122
|
+
inviteId: id,
|
|
123
|
+
orgId,
|
|
124
|
+
actorId: actorFrom(ctx)
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return ids;
|
|
128
|
+
}
|
|
105
129
|
async deleteByOrg(ctx, orgId) {
|
|
106
130
|
const { error } = await this.clients
|
|
107
131
|
.forRequest(ctx)
|
|
@@ -120,6 +144,9 @@ function rowToInvite(row) {
|
|
|
120
144
|
orgId: row.org_id,
|
|
121
145
|
orgRole: row.org_role,
|
|
122
146
|
orgPermissions: row.org_permissions,
|
|
147
|
+
// `?? []` covers a row read through a client whose projection predates the
|
|
148
|
+
// column, not a null default — the column is `not null default '{}'`.
|
|
149
|
+
platformPermissions: (row.platform_permissions ?? []),
|
|
123
150
|
invitedBy: row.invited_by,
|
|
124
151
|
createdAt: row.created_at,
|
|
125
152
|
expiresAt: row.expires_at,
|
|
@@ -135,6 +162,7 @@ function inviteToRow(i) {
|
|
|
135
162
|
org_id: i.orgId,
|
|
136
163
|
org_role: i.orgRole,
|
|
137
164
|
org_permissions: i.orgPermissions,
|
|
165
|
+
platform_permissions: i.platformPermissions ?? [],
|
|
138
166
|
invited_by: i.invitedBy,
|
|
139
167
|
created_at: i.createdAt,
|
|
140
168
|
expires_at: i.expiresAt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseInviteStore.js","sourceRoot":"","sources":["../../src/data/SupabaseInviteStore.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/D,+EAA+E;AAC/E,MAAM,cAAc,GACnB,
|
|
1
|
+
{"version":3,"file":"SupabaseInviteStore.js","sourceRoot":"","sources":["../../src/data/SupabaseInviteStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IShareLinkStore, IEventSink, ShareLink, RequestContext, ListOptions, Page } from '@selvajs/platform';
|
|
1
|
+
import type { IShareLinkStore, IEventSink, OrgShareLink, ShareLink, RequestContext, ListOptions, Page } from '@selvajs/platform';
|
|
2
2
|
import type { ClientBundle } from './client.js';
|
|
3
3
|
/**
|
|
4
4
|
* Share-link store backed by Postgres.
|
|
@@ -6,6 +6,10 @@ import type { ClientBundle } from './client.js';
|
|
|
6
6
|
* `getByTokenHash` and `tryIncrementSolveCount` go through the service-role
|
|
7
7
|
* client and a SECURITY DEFINER RPC, bypassing RLS: the token itself is the
|
|
8
8
|
* credential, not the authenticated user's identity.
|
|
9
|
+
*
|
|
10
|
+
* Reads filter `revoked_at` AND `expires_at` — a dead link must read dead
|
|
11
|
+
* through the store, not only wherever a route remembers to re-check the date.
|
|
12
|
+
* `try_increment_share_link_solve_count` already enforces both server-side.
|
|
9
13
|
*/
|
|
10
14
|
export declare class SupabaseShareLinkStore implements IShareLinkStore {
|
|
11
15
|
private readonly clients;
|
|
@@ -13,6 +17,7 @@ export declare class SupabaseShareLinkStore implements IShareLinkStore {
|
|
|
13
17
|
constructor(clients: ClientBundle, events?: IEventSink);
|
|
14
18
|
create(ctx: RequestContext, link: ShareLink): Promise<void>;
|
|
15
19
|
listByDefinition(ctx: RequestContext, definitionId: string, opts?: ListOptions): Promise<Page<ShareLink>>;
|
|
20
|
+
listByOrg(ctx: RequestContext, orgId: string, opts?: ListOptions): Promise<Page<OrgShareLink>>;
|
|
16
21
|
getById(ctx: RequestContext, id: string): Promise<ShareLink | null>;
|
|
17
22
|
getByTokenHash(_ctx: RequestContext, tokenHash: string): Promise<ShareLink | null>;
|
|
18
23
|
revoke(ctx: RequestContext, id: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseShareLinkStore.d.ts","sourceRoot":"","sources":["../../src/data/SupabaseShareLinkStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,UAAU,EACV,SAAS,EACT,cAAc,EACd,WAAW,EACX,IAAI,EACJ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD
|
|
1
|
+
{"version":3,"file":"SupabaseShareLinkStore.d.ts","sourceRoot":"","sources":["../../src/data/SupabaseShareLinkStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,IAAI,EACJ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD;;;;;;;;;;GAUG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAI5D,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;gBAGlB,OAAO,EAAE,YAAY,EACtC,MAAM,GAAE,UAAgC;IAKnC,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3D,gBAAgB,CACrB,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAgBrB,SAAS,CACd,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAwBxB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAWnE,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAelF,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtD,sBAAsB,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAUtF"}
|
|
@@ -9,6 +9,10 @@ const SHARE_LINK_COLUMNS = 'id, definition_guid, channel, token_hash, name, crea
|
|
|
9
9
|
* `getByTokenHash` and `tryIncrementSolveCount` go through the service-role
|
|
10
10
|
* client and a SECURITY DEFINER RPC, bypassing RLS: the token itself is the
|
|
11
11
|
* credential, not the authenticated user's identity.
|
|
12
|
+
*
|
|
13
|
+
* Reads filter `revoked_at` AND `expires_at` — a dead link must read dead
|
|
14
|
+
* through the store, not only wherever a route remembers to re-check the date.
|
|
15
|
+
* `try_increment_share_link_solve_count` already enforces both server-side.
|
|
12
16
|
*/
|
|
13
17
|
export class SupabaseShareLinkStore {
|
|
14
18
|
clients;
|
|
@@ -39,6 +43,7 @@ export class SupabaseShareLinkStore {
|
|
|
39
43
|
.select(SHARE_LINK_COLUMNS, { count: 'exact' })
|
|
40
44
|
.eq('definition_guid', definitionId)
|
|
41
45
|
.is('revoked_at', null)
|
|
46
|
+
.or(`expires_at.is.null,expires_at.gt.${new Date().toISOString()}`)
|
|
42
47
|
.order('created_at', { ascending: false })
|
|
43
48
|
.range(range.from, range.to);
|
|
44
49
|
if (error)
|
|
@@ -46,6 +51,27 @@ export class SupabaseShareLinkStore {
|
|
|
46
51
|
const items = (data ?? []).map(rowToLink);
|
|
47
52
|
return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
|
|
48
53
|
}
|
|
54
|
+
async listByOrg(ctx, orgId, opts) {
|
|
55
|
+
// `!inner` makes the embeds a filtering join, so `projects.org_id` scopes
|
|
56
|
+
// the whole query — links whose definition or project is soft-deleted drop
|
|
57
|
+
// out for free. RLS narrows this further to orgs the caller leads.
|
|
58
|
+
const range = toRange(opts);
|
|
59
|
+
const { data, error, count } = await this.clients
|
|
60
|
+
.forRequest(ctx)
|
|
61
|
+
.from('share_links')
|
|
62
|
+
.select(`${SHARE_LINK_COLUMNS}, definitions!inner(display_name, deleted_at, projects!inner(id, name, org_id, deleted_at))`, { count: 'exact' })
|
|
63
|
+
.is('revoked_at', null)
|
|
64
|
+
.or(`expires_at.is.null,expires_at.gt.${new Date().toISOString()}`)
|
|
65
|
+
.is('definitions.deleted_at', null)
|
|
66
|
+
.is('definitions.projects.deleted_at', null)
|
|
67
|
+
.eq('definitions.projects.org_id', orgId)
|
|
68
|
+
.order('created_at', { ascending: false })
|
|
69
|
+
.range(range.from, range.to);
|
|
70
|
+
if (error)
|
|
71
|
+
throw mapPostgrestError(error);
|
|
72
|
+
const items = (data ?? []).map((row) => rowToOrgLink(row));
|
|
73
|
+
return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
|
|
74
|
+
}
|
|
49
75
|
async getById(ctx, id) {
|
|
50
76
|
const { data, error } = await this.clients
|
|
51
77
|
.forRequest(ctx)
|
|
@@ -65,6 +91,7 @@ export class SupabaseShareLinkStore {
|
|
|
65
91
|
.select(`${SHARE_LINK_COLUMNS}, definitions!inner(deleted_at)`)
|
|
66
92
|
.eq('token_hash', tokenHash)
|
|
67
93
|
.is('revoked_at', null)
|
|
94
|
+
.or(`expires_at.is.null,expires_at.gt.${new Date().toISOString()}`)
|
|
68
95
|
.is('definitions.deleted_at', null)
|
|
69
96
|
.maybeSingle();
|
|
70
97
|
if (error)
|
|
@@ -92,6 +119,22 @@ export class SupabaseShareLinkStore {
|
|
|
92
119
|
return typeof data === 'number' ? data : null;
|
|
93
120
|
}
|
|
94
121
|
}
|
|
122
|
+
function one(embed) {
|
|
123
|
+
return Array.isArray(embed) ? embed[0] : embed;
|
|
124
|
+
}
|
|
125
|
+
function rowToOrgLink(row) {
|
|
126
|
+
const definition = one(row.definitions);
|
|
127
|
+
const project = one(definition.projects);
|
|
128
|
+
// `tokenHash` is dropped rather than carried: this row is built for a page
|
|
129
|
+
// spanning every definition in the tenant.
|
|
130
|
+
const { tokenHash: _tokenHash, ...rest } = rowToLink(row);
|
|
131
|
+
return {
|
|
132
|
+
...rest,
|
|
133
|
+
definitionName: definition.display_name,
|
|
134
|
+
projectId: project.id,
|
|
135
|
+
projectName: project.name
|
|
136
|
+
};
|
|
137
|
+
}
|
|
95
138
|
function rowToLink(row) {
|
|
96
139
|
return {
|
|
97
140
|
id: row.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseShareLinkStore.js","sourceRoot":"","sources":["../../src/data/SupabaseShareLinkStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SupabaseShareLinkStore.js","sourceRoot":"","sources":["../../src/data/SupabaseShareLinkStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* whenever a migration is added — `migration-head.test.ts` asserts it
|
|
4
4
|
* matches the migrations directory, so CI catches drift.
|
|
5
5
|
*/
|
|
6
|
-
export declare const EXPECTED_MIGRATION_HEAD = "
|
|
6
|
+
export declare const EXPECTED_MIGRATION_HEAD = "20260817200000";
|
|
7
7
|
//# sourceMappingURL=migrationHead.d.ts.map
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* whenever a migration is added — `migration-head.test.ts` asserts it
|
|
4
4
|
* matches the migrations directory, so CI catches drift.
|
|
5
5
|
*/
|
|
6
|
-
export const EXPECTED_MIGRATION_HEAD = '
|
|
6
|
+
export const EXPECTED_MIGRATION_HEAD = '20260817200000';
|
|
7
7
|
//# sourceMappingURL=migrationHead.js.map
|
|
@@ -18,6 +18,7 @@ export declare class SupabasePlatformPermissionStore implements IPlatformPermiss
|
|
|
18
18
|
getFor(ctx: RequestContext, userId: string): Promise<PlatformPermission[]>;
|
|
19
19
|
getForBatch(ctx: RequestContext, userIds: readonly string[]): Promise<Map<string, PlatformPermission[]>>;
|
|
20
20
|
set(ctx: RequestContext, userId: string, permissions: readonly PlatformPermission[]): Promise<UserManagementResult>;
|
|
21
|
+
claimFirstInstanceAdmin(_ctx: RequestContext, userId: string, permissions: readonly PlatformPermission[]): Promise<boolean>;
|
|
21
22
|
hasInstanceAdmin(_ctx: RequestContext): Promise<boolean>;
|
|
22
23
|
countInstanceAdminsExcluding(_ctx: RequestContext, excludeUserId: string): Promise<number>;
|
|
23
24
|
private countOtherEnabledAdmins;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabasePlatformPermissionStore.d.ts","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"SupabasePlatformPermissionStore.d.ts","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,MAAM,mBAAmB,CAAC;AAO3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,+BAAgC,YAAW,wBAAwB;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAElD,OAAO,CAAC,MAAM;IAIR,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAW1E,WAAW,CAChB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAevC,GAAG,CACR,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC;IAyB1B,uBAAuB,CAC5B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,OAAO,CAAC;IAYb,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD,4BAA4B,CAAC,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAIlF,uBAAuB;CAUrC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProviderError, hasPermission, ALL_PLATFORM_PERMISSIONS } from '@selvajs/platform';
|
|
1
|
+
import { ProviderError, hasPermission, assertNotShareContext, ALL_PLATFORM_PERMISSIONS } from '@selvajs/platform';
|
|
2
2
|
/**
|
|
3
3
|
* Reads and writes `public.user_profiles.platform_permissions` (auto-seeded
|
|
4
4
|
* by the `handle_new_auth_user` trigger). Service-role throughout — RLS on
|
|
@@ -30,7 +30,7 @@ export class SupabasePlatformPermissionStore {
|
|
|
30
30
|
return filterValid(data?.platform_permissions ?? []);
|
|
31
31
|
}
|
|
32
32
|
async getForBatch(ctx, userIds) {
|
|
33
|
-
|
|
33
|
+
assertCanReadBatch(ctx);
|
|
34
34
|
const out = new Map();
|
|
35
35
|
if (userIds.length === 0)
|
|
36
36
|
return out;
|
|
@@ -47,30 +47,40 @@ export class SupabasePlatformPermissionStore {
|
|
|
47
47
|
}
|
|
48
48
|
async set(ctx, userId, permissions) {
|
|
49
49
|
assertAdmin(ctx);
|
|
50
|
+
// The §2 last-admin check lives inside the UPDATE's WHERE clause, so it
|
|
51
|
+
// is evaluated under the row lock that guards the write. Doing it here
|
|
52
|
+
// as count-then-update let two concurrent demotions each observe the
|
|
53
|
+
// other as "another admin exists" and both commit, leaving zero admins.
|
|
54
|
+
const { data, error } = await this.client().rpc('set_platform_permissions', {
|
|
55
|
+
p_user_id: userId,
|
|
56
|
+
p_permissions: [...permissions]
|
|
57
|
+
});
|
|
58
|
+
if (error)
|
|
59
|
+
throw mapError(error);
|
|
60
|
+
if ((data ?? 0) > 0)
|
|
61
|
+
return 'ok';
|
|
62
|
+
// Zero rows written: either the row is absent, or the predicate refused
|
|
63
|
+
// the demotion. Only the second is `last_admin`, so disambiguate.
|
|
50
64
|
const { data: existing, error: fetchError } = await this.client()
|
|
51
65
|
.from('user_profiles')
|
|
52
|
-
.select('
|
|
66
|
+
.select('user_id')
|
|
53
67
|
.eq('user_id', userId)
|
|
54
68
|
.maybeSingle();
|
|
55
69
|
if (fetchError)
|
|
56
70
|
throw mapError(fetchError);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
const { error } = await this.client()
|
|
68
|
-
.from('user_profiles')
|
|
69
|
-
.update({ platform_permissions: [...permissions] })
|
|
70
|
-
.eq('user_id', userId);
|
|
71
|
+
return existing ? 'last_admin' : 'not_found';
|
|
72
|
+
}
|
|
73
|
+
async claimFirstInstanceAdmin(_ctx, userId, permissions) {
|
|
74
|
+
// No `assertAdmin`: by definition nobody holds `instance_admin` when this
|
|
75
|
+
// succeeds. The RPC takes an advisory lock and re-reads inside it, so a
|
|
76
|
+
// second concurrent signer blocks and then correctly loses.
|
|
77
|
+
const { data, error } = await this.client().rpc('claim_first_instance_admin', {
|
|
78
|
+
p_user_id: userId,
|
|
79
|
+
p_permissions: [...permissions]
|
|
80
|
+
});
|
|
71
81
|
if (error)
|
|
72
82
|
throw mapError(error);
|
|
73
|
-
return
|
|
83
|
+
return data === true;
|
|
74
84
|
}
|
|
75
85
|
async hasInstanceAdmin(_ctx) {
|
|
76
86
|
const { count, error } = await this.client()
|
|
@@ -101,16 +111,38 @@ const VALID_PERMISSIONS = new Set(ALL_PLATFORM_PERMISSIONS);
|
|
|
101
111
|
function filterValid(raw) {
|
|
102
112
|
return raw.filter((p) => VALID_PERMISSIONS.has(p));
|
|
103
113
|
}
|
|
114
|
+
// Reading one row and reading many must agree, and both must match the local
|
|
115
|
+
// provider — §8 gives `manage_instance_users` the user-admin surface, which
|
|
116
|
+
// cannot render its locks without knowing who holds `instance_admin`. This
|
|
117
|
+
// store denied both until now, so on Supabase `/admin/users` failed for exactly
|
|
118
|
+
// the role it exists to serve.
|
|
119
|
+
//
|
|
120
|
+
// Read access is not authority: `set` stays `instance_admin`-only via
|
|
121
|
+
// `assertAdmin`, and the delete/disable routes gate separately.
|
|
104
122
|
function assertCanRead(ctx, userId) {
|
|
123
|
+
assertNotShareContext(ctx, 'read permissions');
|
|
105
124
|
if (ctx.system)
|
|
106
125
|
return;
|
|
107
126
|
if (ctx.userId === userId)
|
|
108
127
|
return;
|
|
109
128
|
if (hasPermission(ctx, 'instance_admin'))
|
|
110
129
|
return;
|
|
130
|
+
if (hasPermission(ctx, 'manage_instance_users'))
|
|
131
|
+
return;
|
|
111
132
|
throw new ProviderError('Forbidden: cannot read another user’s permissions', 403);
|
|
112
133
|
}
|
|
134
|
+
function assertCanReadBatch(ctx) {
|
|
135
|
+
assertNotShareContext(ctx, 'read permissions');
|
|
136
|
+
if (ctx.system)
|
|
137
|
+
return;
|
|
138
|
+
if (hasPermission(ctx, 'instance_admin'))
|
|
139
|
+
return;
|
|
140
|
+
if (hasPermission(ctx, 'manage_instance_users'))
|
|
141
|
+
return;
|
|
142
|
+
throw new ProviderError('Forbidden: instance admin or manage_instance_users required', 403);
|
|
143
|
+
}
|
|
113
144
|
function assertAdmin(ctx) {
|
|
145
|
+
assertNotShareContext(ctx, 'manage permissions');
|
|
114
146
|
if (ctx.system)
|
|
115
147
|
return;
|
|
116
148
|
if (hasPermission(ctx, 'instance_admin'))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabasePlatformPermissionStore.js","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"AAMA,OAAO,
|
|
1
|
+
{"version":3,"file":"SupabasePlatformPermissionStore.js","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProviderError, hasPermission } from '@selvajs/platform';
|
|
1
|
+
import { ProviderError, hasPermission, assertNotShareContext } from '@selvajs/platform';
|
|
2
2
|
/**
|
|
3
3
|
* Backed by `public.user_profiles` (one row per `auth.users.id`), auto-seeded
|
|
4
4
|
* by the `handle_new_auth_user` trigger on signup — this store never inserts,
|
|
@@ -108,6 +108,7 @@ export class SupabaseUserProfileProvider {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
function assertCanAccess(ctx, userId) {
|
|
111
|
+
assertNotShareContext(ctx, 'access user profiles');
|
|
111
112
|
if (ctx.system)
|
|
112
113
|
return;
|
|
113
114
|
if (ctx.userId === userId)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseUserProfileProvider.js","sourceRoot":"","sources":["../../src/userProfile/SupabaseUserProfileProvider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"SupabaseUserProfileProvider.js","sourceRoot":"","sources":["../../src/userProfile/SupabaseUserProfileProvider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selvajs/supabase-provider",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Supabase (Auth + Postgres + Storage) implementations of @selvajs/platform interfaces",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "VektorNode",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@supabase/supabase-js": "^2.112.2",
|
|
74
74
|
"sharp": "^0.35.3",
|
|
75
|
-
"@selvajs/platform": "^0.
|
|
75
|
+
"@selvajs/platform": "^0.19.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@types/node": "^
|
|
78
|
+
"@types/node": "^24.13.3",
|
|
79
79
|
"supabase": "^2.112.0",
|
|
80
80
|
"typescript": "~6.0.3",
|
|
81
81
|
"vitest": "^4.1.10",
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
-- Cache the compute-extracted UI schema on each definition version.
|
|
3
3
|
--
|
|
4
4
|
-- The render path used to re-fetch the schema from Rhino.Compute on every load;
|
|
5
|
-
-- it is now extracted + validated once at upload and stored here.
|
|
6
|
-
-- packages/selva/specs/SchemaCaching.md.
|
|
5
|
+
-- it is now extracted + validated once at upload and stored here.
|
|
7
6
|
--
|
|
8
7
|
-- `change_note` is added in the same migration: it is referenced by
|
|
9
8
|
-- SupabaseDefinitionStore (versionToRow / rowToVersion) but was never created
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- selva.invites.platform_permissions — instance-wide grants carried by an invite
|
|
3
|
+
-- ============================================================================
|
|
4
|
+
--
|
|
5
|
+
-- Invites could only ever grant org scope, so the sole way to create a second
|
|
6
|
+
-- instance admin was the admin-sets-password form on /admin/users — a form that
|
|
7
|
+
-- cannot exist under a header-auth/IdP deployment, where Selva never holds a
|
|
8
|
+
-- credential. Removing that form without this column would leave such a
|
|
9
|
+
-- deployment permanently stuck at one admin.
|
|
10
|
+
--
|
|
11
|
+
-- Empty for virtually every row: the mint route rejects a non-empty value unless
|
|
12
|
+
-- the caller already holds instance_admin, since anyone who can write here can
|
|
13
|
+
-- escalate past org scope.
|
|
14
|
+
|
|
15
|
+
alter table selva.invites
|
|
16
|
+
add column if not exists platform_permissions text[] not null default '{}';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- Org-wide share-link roster (spec §7, §10)
|
|
3
|
+
--
|
|
4
|
+
-- A share link is a bearer credential: the URL is the whole authentication.
|
|
5
|
+
-- Until now the only read was per-definition and required edit rights on that
|
|
6
|
+
-- definition, so "what currently reaches my org's data?" could only be
|
|
7
|
+
-- answered by walking every definition by hand. Offboarding depended on it.
|
|
8
|
+
--
|
|
9
|
+
-- Adds the read authority org leadership needs for that roster, plus the
|
|
10
|
+
-- index the link -> definition -> project join walks.
|
|
11
|
+
-- ============================================================================
|
|
12
|
+
|
|
13
|
+
-- Org leadership reads links across the whole tenant, including projects they
|
|
14
|
+
-- are not a member of. Deliberately SELECT-only and deliberately separate from
|
|
15
|
+
-- the editor policy above it: revoking still requires edit rights on the
|
|
16
|
+
-- parent definition, so seeing the roster never implies authority over it.
|
|
17
|
+
--
|
|
18
|
+
-- Gated on `manage_org_members` rather than `manage_projects`: this is the
|
|
19
|
+
-- offboarding permission, and the roster's purpose is answering "what did the
|
|
20
|
+
-- leaver leave behind?". `manage_projects` can be handed to a plain member
|
|
21
|
+
-- (§11), who has no business enumerating every credential in the tenant.
|
|
22
|
+
create policy "share_links: org leadership can read the roster"
|
|
23
|
+
on selva.share_links for select
|
|
24
|
+
to authenticated
|
|
25
|
+
using (
|
|
26
|
+
exists (
|
|
27
|
+
select 1
|
|
28
|
+
from selva.definitions d
|
|
29
|
+
join selva.projects p on p.id = d.project_id
|
|
30
|
+
where d.guid = share_links.definition_guid
|
|
31
|
+
and d.deleted_at is null
|
|
32
|
+
and p.deleted_at is null
|
|
33
|
+
and selva.has_org_permission(p.org_id, 'manage_org_members')
|
|
34
|
+
)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
-- The roster orders by created_at across the whole org, where the existing
|
|
38
|
+
-- index is per-definition. Partial on the same `revoked_at is null` predicate
|
|
39
|
+
-- the reads filter by.
|
|
40
|
+
create index if not exists idx_share_links_created
|
|
41
|
+
on selva.share_links(created_at desc)
|
|
42
|
+
where revoked_at is null;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- RLS re-enforces the access rules independently (audit finding 12)
|
|
3
|
+
--
|
|
4
|
+
-- `rules.ts` promises: "Mutating store methods MUST re-enforce the same
|
|
5
|
+
-- predicate independently (RLS in SQL, code in local/JSON)." Three policies
|
|
6
|
+
-- had drifted from the rule they are supposed to mirror.
|
|
7
|
+
--
|
|
8
|
+
-- The one that bites today is project mutation. `canManage` and
|
|
9
|
+
-- `canEditProjectSettings` both resolve to "project member with role=owner",
|
|
10
|
+
-- while the policies read `projects.owner_id`. Those agree right up until a
|
|
11
|
+
-- Reclaim: `POST /projects/{id}/reclaim` adds an owner-role `project_members`
|
|
12
|
+
-- row on purpose and deliberately does NOT demote `owner_id`, so afterwards
|
|
13
|
+
-- the app layer says yes and RLS says no. Renaming a reclaimed project fails
|
|
14
|
+
-- with an RLS violation on Supabase and succeeds on local — reclaim is
|
|
15
|
+
-- functionally broken for settings edits on exactly one provider.
|
|
16
|
+
--
|
|
17
|
+
-- Two divergences are deliberately NOT closed here; see the bottom of this
|
|
18
|
+
-- file for why (`platform` visibility, `ALLOW_CROSS_ORG_PUBLIC`).
|
|
19
|
+
-- ============================================================================
|
|
20
|
+
|
|
21
|
+
-- ----------------------------------------------------------------------------
|
|
22
|
+
-- 1. Project mutation follows member role, not `owner_id`
|
|
23
|
+
-- ----------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
-- `owner_id` stays on the row: it records who created the project and drives
|
|
26
|
+
-- the `on delete cascade`. It is simply not the authority for "may I edit
|
|
27
|
+
-- this?" — `canManage(input)` is `member?.role === 'owner'`, and a project
|
|
28
|
+
-- can have several owners (reclaim adds one; so does the members API).
|
|
29
|
+
create or replace function selva.is_project_owner(p uuid)
|
|
30
|
+
returns boolean
|
|
31
|
+
language sql stable security definer set search_path = public
|
|
32
|
+
as $$
|
|
33
|
+
select exists (
|
|
34
|
+
select 1 from selva.project_members
|
|
35
|
+
where project_id = p
|
|
36
|
+
and user_id = auth.uid()
|
|
37
|
+
and role = 'owner'
|
|
38
|
+
and deleted_at is null
|
|
39
|
+
);
|
|
40
|
+
$$;
|
|
41
|
+
|
|
42
|
+
drop policy if exists "projects: owners can update" on selva.projects;
|
|
43
|
+
create policy "projects: owners can update"
|
|
44
|
+
on selva.projects for update
|
|
45
|
+
to authenticated
|
|
46
|
+
using (selva.is_instance_admin() or selva.is_project_owner(id))
|
|
47
|
+
with check (selva.is_instance_admin() or selva.is_project_owner(id));
|
|
48
|
+
|
|
49
|
+
drop policy if exists "projects: owners can delete" on selva.projects;
|
|
50
|
+
create policy "projects: owners can delete"
|
|
51
|
+
on selva.projects for delete
|
|
52
|
+
to authenticated
|
|
53
|
+
using (selva.is_instance_admin() or selva.is_project_owner(id));
|
|
54
|
+
|
|
55
|
+
-- The three `project_members` write policies inlined the same `owner_id`
|
|
56
|
+
-- lookup. Same substitution, and now they share the helper rather than three
|
|
57
|
+
-- copies of a subquery that has to keep agreeing with itself.
|
|
58
|
+
drop policy if exists "project_members: managers can insert" on selva.project_members;
|
|
59
|
+
create policy "project_members: managers can insert"
|
|
60
|
+
on selva.project_members for insert
|
|
61
|
+
to authenticated
|
|
62
|
+
with check (selva.is_instance_admin() or selva.is_project_owner(project_id));
|
|
63
|
+
|
|
64
|
+
drop policy if exists "project_members: managers can update" on selva.project_members;
|
|
65
|
+
create policy "project_members: managers can update"
|
|
66
|
+
on selva.project_members for update
|
|
67
|
+
to authenticated
|
|
68
|
+
using (selva.is_instance_admin() or selva.is_project_owner(project_id))
|
|
69
|
+
with check (selva.is_instance_admin() or selva.is_project_owner(project_id));
|
|
70
|
+
|
|
71
|
+
drop policy if exists "project_members: managers can delete" on selva.project_members;
|
|
72
|
+
create policy "project_members: managers can delete"
|
|
73
|
+
on selva.project_members for delete
|
|
74
|
+
to authenticated
|
|
75
|
+
using (selva.is_instance_admin() or selva.is_project_owner(project_id));
|
|
76
|
+
|
|
77
|
+
-- Two writes add an owner row for someone `is_project_owner` does not yet
|
|
78
|
+
-- cover, because the row being written is what would make it true:
|
|
79
|
+
--
|
|
80
|
+
-- * `createProject` inserts the project, then upserts the creator's own owner
|
|
81
|
+
-- row. `owner_id` still answers this correctly — it is set at creation, and
|
|
82
|
+
-- `user_id = auth.uid()` bounds it to the self-seeding case.
|
|
83
|
+
-- * Reclaim adds an org admin who was never a project member. That is the
|
|
84
|
+
-- entire point of the escape hatch, so RLS mirrors `canReclaim` (org
|
|
85
|
+
-- owner/admin, matching tenancy) instead of the project-owner rule.
|
|
86
|
+
--
|
|
87
|
+
-- Both are self-writes of an owner row, so they share one predicate.
|
|
88
|
+
create or replace function selva.may_seed_project_owner(p uuid)
|
|
89
|
+
returns boolean
|
|
90
|
+
language sql stable security definer set search_path = public
|
|
91
|
+
as $$
|
|
92
|
+
select exists (
|
|
93
|
+
select 1 from selva.projects proj
|
|
94
|
+
where proj.id = p
|
|
95
|
+
and proj.deleted_at is null
|
|
96
|
+
and (proj.owner_id = auth.uid() or selva.is_org_admin(proj.org_id))
|
|
97
|
+
);
|
|
98
|
+
$$;
|
|
99
|
+
|
|
100
|
+
-- Both writes go through `addProjectMember`, which UPSERTs so a soft-deleted
|
|
101
|
+
-- row reactivates in place instead of throwing duplicate-key. Postgres checks
|
|
102
|
+
-- an upsert against the INSERT policy *and* the UPDATE policy, so a seeding
|
|
103
|
+
-- rule that only covers INSERT rejects the very first `createProject` — the
|
|
104
|
+
-- ON CONFLICT arm has no UPDATE policy to fall back on. Both arms, always.
|
|
105
|
+
drop policy if exists "project_members: seeding an owner row" on selva.project_members;
|
|
106
|
+
create policy "project_members: seeding an owner row"
|
|
107
|
+
on selva.project_members for insert
|
|
108
|
+
to authenticated
|
|
109
|
+
with check (
|
|
110
|
+
user_id = auth.uid()
|
|
111
|
+
and role = 'owner'
|
|
112
|
+
and selva.may_seed_project_owner(project_id)
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
drop policy if exists "project_members: reactivating a seeded owner row" on selva.project_members;
|
|
116
|
+
create policy "project_members: reactivating a seeded owner row"
|
|
117
|
+
on selva.project_members for update
|
|
118
|
+
to authenticated
|
|
119
|
+
using (user_id = auth.uid() and selva.may_seed_project_owner(project_id))
|
|
120
|
+
with check (
|
|
121
|
+
user_id = auth.uid()
|
|
122
|
+
and role = 'owner'
|
|
123
|
+
and selva.may_seed_project_owner(project_id)
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
-- ----------------------------------------------------------------------------
|
|
127
|
+
-- 2. The member roster is not part of project visibility
|
|
128
|
+
-- ----------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
-- The SELECT policy was `visible_project(project_id)`, which on a `public`
|
|
131
|
+
-- project means every authenticated user on the instance could enumerate the
|
|
132
|
+
-- roster. Seeing a project is not the same as seeing who is in it: §11 keeps
|
|
133
|
+
-- membership listings for leadership, and the app layer never offers the
|
|
134
|
+
-- roster to a non-member.
|
|
135
|
+
--
|
|
136
|
+
-- `is_project_member` covers the ordinary case (members see their peers) and
|
|
137
|
+
-- `is_org_admin` covers leadership, who manage membership and need to read it
|
|
138
|
+
-- to do so.
|
|
139
|
+
--
|
|
140
|
+
-- RLS alone would make Supabase quietly stricter than local, which is the drift
|
|
141
|
+
-- this migration exists to remove, only pointing the other way. The decision is
|
|
142
|
+
-- therefore also made at the route: `/projects` now loads the roster only for
|
|
143
|
+
-- projects the caller `canManage`, so both providers agree because neither
|
|
144
|
+
-- store is deciding. This policy is the backstop under that.
|
|
145
|
+
drop policy if exists "project_members: visible to project members" on selva.project_members;
|
|
146
|
+
create policy "project_members: visible to project members"
|
|
147
|
+
on selva.project_members for select
|
|
148
|
+
to authenticated
|
|
149
|
+
using (
|
|
150
|
+
selva.is_instance_admin()
|
|
151
|
+
or user_id = auth.uid()
|
|
152
|
+
or selva.is_project_member(project_id)
|
|
153
|
+
or exists (
|
|
154
|
+
select 1 from selva.projects p
|
|
155
|
+
where p.id = project_id and selva.is_org_admin(p.org_id)
|
|
156
|
+
)
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
-- ----------------------------------------------------------------------------
|
|
160
|
+
-- Deliberately unchanged
|
|
161
|
+
-- ----------------------------------------------------------------------------
|
|
162
|
+
--
|
|
163
|
+
-- `visible_project` has no `platform` branch, and gets none here. The
|
|
164
|
+
-- `projects.visibility` CHECK constraint only admits public/org/private, and
|
|
165
|
+
-- `IPlatformProjectGrantStore` on Supabase is a stub that throws 501 — the
|
|
166
|
+
-- feature does not exist on this provider, so there is no grant table for a
|
|
167
|
+
-- policy to consult. Adding the branch is part of shipping platform projects
|
|
168
|
+
-- on Supabase, not part of closing a drift. Until then the CHECK fails closed.
|
|
169
|
+
--
|
|
170
|
+
-- `public` still ignores `ALLOW_CROSS_ORG_PUBLIC`, so with the flag off RLS
|
|
171
|
+
-- is more permissive than `canView`. Postgres cannot read the app's env, and
|
|
172
|
+
-- mirroring a deploy-time flag into the database means a second source of
|
|
173
|
+
-- truth that can disagree with the first — the failure mode is worse than the
|
|
174
|
+
-- one it fixes. The app layer stays authoritative for that flag; RLS remains
|
|
175
|
+
-- the backstop for everything that is a property of the data.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- The sole-instance_admin invariant becomes atomic (audit finding 17)
|
|
3
|
+
--
|
|
4
|
+
-- §2: "Any operation that would leave the instance with zero instance_admins —
|
|
5
|
+
-- revoking, deleting, disabling — is rejected by the data layer." It was
|
|
6
|
+
-- enforced as read-then-write with nothing in between:
|
|
7
|
+
--
|
|
8
|
+
-- others = count admins where user_id <> target and not disabled
|
|
9
|
+
-- if others = 0 -> refuse
|
|
10
|
+
-- update user_profiles set platform_permissions = ...
|
|
11
|
+
--
|
|
12
|
+
-- Two admins demoting each other at the same moment both read `others = 1`,
|
|
13
|
+
-- both pass the check, and both commit. Zero admins, and the instance can no
|
|
14
|
+
-- longer be administered through the UI at all. Supabase is the worse case:
|
|
15
|
+
-- the app runs on several instances, so the two requests are genuinely
|
|
16
|
+
-- concurrent rather than interleaved on one event loop.
|
|
17
|
+
--
|
|
18
|
+
-- §7's share-link solve cap already solved this shape — check and write in a
|
|
19
|
+
-- single statement, with the predicate in the WHERE clause so Postgres
|
|
20
|
+
-- evaluates it against the row it is about to lock. This applies the same
|
|
21
|
+
-- pattern. `try_increment_share_link_solve_count` is the template.
|
|
22
|
+
-- ============================================================================
|
|
23
|
+
|
|
24
|
+
-- Returns the row count so the caller can tell the outcomes apart:
|
|
25
|
+
-- 1 -> written
|
|
26
|
+
-- 0 -> refused (would drop the last enabled admin) OR row absent
|
|
27
|
+
-- The caller disambiguates with a follow-up existence check, which is safe
|
|
28
|
+
-- because a missing row cannot become present concurrently in a way that
|
|
29
|
+
-- matters — `ensureUser` seeds rows, it never removes them.
|
|
30
|
+
--
|
|
31
|
+
-- A bare `exists` in the UPDATE's WHERE clause is NOT enough, and the
|
|
32
|
+
-- conformance suite proves it: under READ COMMITTED the subquery reads the
|
|
33
|
+
-- snapshot taken when the statement began, so four concurrent demotions each
|
|
34
|
+
-- see the other three as still-admins and all four commit. The predicate has
|
|
35
|
+
-- to take real locks, hence the explicit `for update` below.
|
|
36
|
+
create or replace function selva.set_platform_permissions(
|
|
37
|
+
p_user_id uuid,
|
|
38
|
+
p_permissions text[]
|
|
39
|
+
)
|
|
40
|
+
returns integer
|
|
41
|
+
language plpgsql security definer set search_path = public
|
|
42
|
+
as $$
|
|
43
|
+
declare
|
|
44
|
+
v_is_demotion boolean;
|
|
45
|
+
v_others integer;
|
|
46
|
+
v_updated integer;
|
|
47
|
+
begin
|
|
48
|
+
-- Lock the target first, always in this order (target, then survivors), so
|
|
49
|
+
-- two demotions of different users can't deadlock by grabbing each other's
|
|
50
|
+
-- rows in the opposite sequence.
|
|
51
|
+
select 'instance_admin' = any(platform_permissions)
|
|
52
|
+
and not ('instance_admin' = any(p_permissions))
|
|
53
|
+
into v_is_demotion
|
|
54
|
+
from selva.user_profiles
|
|
55
|
+
where user_id = p_user_id
|
|
56
|
+
for update;
|
|
57
|
+
|
|
58
|
+
if not found then
|
|
59
|
+
return 0;
|
|
60
|
+
end if;
|
|
61
|
+
|
|
62
|
+
if v_is_demotion then
|
|
63
|
+
-- `for update` makes concurrent demotions serialize on the surviving
|
|
64
|
+
-- admin rows: the second waits for the first to commit, then re-reads
|
|
65
|
+
-- and observes the demotion it would otherwise have raced through.
|
|
66
|
+
-- Counted by locking the rows first and re-checking them after, because
|
|
67
|
+
-- a lock wait re-reads the row and it may no longer qualify.
|
|
68
|
+
perform 1
|
|
69
|
+
from selva.user_profiles
|
|
70
|
+
where user_id <> p_user_id
|
|
71
|
+
and disabled = false
|
|
72
|
+
and 'instance_admin' = any(platform_permissions)
|
|
73
|
+
for update;
|
|
74
|
+
|
|
75
|
+
select count(*) into v_others
|
|
76
|
+
from selva.user_profiles
|
|
77
|
+
where user_id <> p_user_id
|
|
78
|
+
and disabled = false
|
|
79
|
+
and 'instance_admin' = any(platform_permissions);
|
|
80
|
+
|
|
81
|
+
if v_others = 0 then
|
|
82
|
+
return 0;
|
|
83
|
+
end if;
|
|
84
|
+
end if;
|
|
85
|
+
|
|
86
|
+
update selva.user_profiles
|
|
87
|
+
set platform_permissions = p_permissions
|
|
88
|
+
where user_id = p_user_id;
|
|
89
|
+
|
|
90
|
+
get diagnostics v_updated = row_count;
|
|
91
|
+
return v_updated;
|
|
92
|
+
end;
|
|
93
|
+
$$;
|
|
94
|
+
|
|
95
|
+
-- Service-role only: `SupabasePlatformPermissionStore` runs service-role
|
|
96
|
+
-- throughout and gates on `assertAdmin` in code (RLS on `user_profiles` is too
|
|
97
|
+
-- coarse for cross-user writes). Granting this to `authenticated` would hand
|
|
98
|
+
-- every logged-in user a permission-write bypassing that gate.
|
|
99
|
+
revoke execute on function selva.set_platform_permissions(uuid, text[]) from public;
|
|
100
|
+
grant execute on function selva.set_platform_permissions(uuid, text[]) to service_role;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- First-admin bootstrap becomes atomic (audit finding 20)
|
|
3
|
+
--
|
|
4
|
+
-- §2: "first signer wins" on a fresh instance. It was enforced as
|
|
5
|
+
-- read-then-write in `bootstrapUserSession`:
|
|
6
|
+
--
|
|
7
|
+
-- if not hasInstanceAdmin() then set(user, ALL_PLATFORM_PERMISSIONS)
|
|
8
|
+
--
|
|
9
|
+
-- On a single-tenant install with no BOOTSTRAP_INSTANCE_ADMIN_EMAIL set,
|
|
10
|
+
-- `shouldBootstrapAdmin` returns true for ANY signer — so two different people
|
|
11
|
+
-- signing in at the same moment both observe "no admin" and both are granted
|
|
12
|
+
-- every platform permission, permanently. Supabase is the worse case: the app
|
|
13
|
+
-- runs on several instances, so the two requests are genuinely concurrent
|
|
14
|
+
-- rather than interleaved on one event loop.
|
|
15
|
+
--
|
|
16
|
+
-- Same shape as `set_platform_permissions` (finding 17) pointing the other
|
|
17
|
+
-- way: that one refuses to drop the LAST admin, this one refuses to create a
|
|
18
|
+
-- SECOND first admin. The lesson from that migration applies here verbatim —
|
|
19
|
+
-- a bare `not exists (...)` in the UPDATE's WHERE clause is not enough, because
|
|
20
|
+
-- under READ COMMITTED the subquery reads the snapshot taken when the statement
|
|
21
|
+
-- began and both racers see an empty table. The predicate has to take a real
|
|
22
|
+
-- lock.
|
|
23
|
+
--
|
|
24
|
+
-- There is no row to lock here (the point is that no admin row exists), so this
|
|
25
|
+
-- takes a transaction-scoped advisory lock instead. The second caller blocks,
|
|
26
|
+
-- then re-reads after the first commits and correctly sees an admin.
|
|
27
|
+
-- ============================================================================
|
|
28
|
+
|
|
29
|
+
-- Returns true if THIS call claimed the instance, false if an admin already
|
|
30
|
+
-- existed or the target profile is absent. Idempotent under concurrency: at
|
|
31
|
+
-- most one caller can ever observe true for a given instance.
|
|
32
|
+
create or replace function selva.claim_first_instance_admin(
|
|
33
|
+
p_user_id uuid,
|
|
34
|
+
p_permissions text[]
|
|
35
|
+
)
|
|
36
|
+
returns boolean
|
|
37
|
+
language plpgsql security definer set search_path = public
|
|
38
|
+
as $$
|
|
39
|
+
declare
|
|
40
|
+
v_updated integer;
|
|
41
|
+
begin
|
|
42
|
+
-- Transaction-scoped, released on commit/rollback. The key is an arbitrary
|
|
43
|
+
-- constant naming this invariant — every caller of this function contends
|
|
44
|
+
-- on the same one, which is exactly the intent: bootstrap happens once per
|
|
45
|
+
-- instance, so serializing all attempts costs nothing after the first.
|
|
46
|
+
perform pg_advisory_xact_lock(hashtext('selva.first_instance_admin'));
|
|
47
|
+
|
|
48
|
+
-- Re-read INSIDE the lock. A caller that blocked here started before the
|
|
49
|
+
-- winner committed, so its own earlier `hasInstanceAdmin()` read is stale.
|
|
50
|
+
if exists (
|
|
51
|
+
select 1 from selva.user_profiles
|
|
52
|
+
where disabled = false
|
|
53
|
+
and 'instance_admin' = any(platform_permissions)
|
|
54
|
+
) then
|
|
55
|
+
return false;
|
|
56
|
+
end if;
|
|
57
|
+
|
|
58
|
+
update selva.user_profiles
|
|
59
|
+
set platform_permissions = p_permissions
|
|
60
|
+
where user_id = p_user_id;
|
|
61
|
+
|
|
62
|
+
get diagnostics v_updated = row_count;
|
|
63
|
+
return v_updated = 1;
|
|
64
|
+
end;
|
|
65
|
+
$$;
|
|
66
|
+
|
|
67
|
+
-- Service-role only, for the same reason as `set_platform_permissions`:
|
|
68
|
+
-- granting this to `authenticated` would let any logged-in user attempt a
|
|
69
|
+
-- platform-permission write. It fails closed once an admin exists, but the
|
|
70
|
+
-- bootstrap window is precisely when that is not yet true.
|
|
71
|
+
revoke execute on function selva.claim_first_instance_admin(uuid, text[]) from public;
|
|
72
|
+
grant execute on function selva.claim_first_instance_admin(uuid, text[]) to service_role;
|