@absolutejs/auth 0.84.0 → 0.86.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/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.86.0 — 2026-09-23
10
+
11
+ ### Breaking
12
+
13
+ - **Bind organization invitation acceptance to a verified email and atomically consume the invitation with membership creation. Deny expired, revoked, missing-organization and suspended-member invitations; preserve existing member roles.** (`acceptInvitation`, `OrganizationsConfig`, `OrganizationStore`, `listUserOrganizations`, `organizationRoutes`)
14
+ _Migration:_ Configure organizations.getVerifiedEmail with provider-verified email evidence. Direct acceptInvitation callers must supply verifiedEmail. Custom OrganizationStore adapters must implement atomic acceptInvitation; older adapters fail closed.
15
+
16
+ ## 0.85.0 — 2026-09-23
17
+
18
+ ### Breaking
19
+
20
+ - **Use the native Citra Neon provider for Auth configuration and linked-account refresh** (`createNeonProviderConfiguration`, `neonProviderConfiguration`)
21
+ _Migration:_ Move createNeonProviderConfiguration results from customProviders.neon to providersConfiguration.neon. Neon is now a built-in Citra provider; credentials, scopes and offlineAccess inputs are unchanged.
22
+
23
+ ### Changed
24
+
25
+ - **Include Neon in the typed built-in provider registry and configuration resolution** (`buildClientProviders`, `resolveProviderClientConfiguration`)
26
+
9
27
  ## 0.84.0 — 2026-09-23
10
28
 
11
29
  ### Added
package/changelog.json CHANGED
@@ -2,6 +2,53 @@
2
2
  "contract": 1,
3
3
  "name": "@absolutejs/auth",
4
4
  "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "kind": "breaking",
9
+ "migration": {
10
+ "instruction": "Configure organizations.getVerifiedEmail with provider-verified email evidence. Direct acceptInvitation callers must supply verifiedEmail. Custom OrganizationStore adapters must implement atomic acceptInvitation; older adapters fail closed.",
11
+ "manual": true
12
+ },
13
+ "summary": "Bind organization invitation acceptance to a verified email and atomically consume the invitation with membership creation. Deny expired, revoked, missing-organization and suspended-member invitations; preserve existing member roles.",
14
+ "symbols": [
15
+ "acceptInvitation",
16
+ "OrganizationsConfig",
17
+ "OrganizationStore",
18
+ "listUserOrganizations",
19
+ "organizationRoutes"
20
+ ]
21
+ }
22
+ ],
23
+ "date": "2026-09-23",
24
+ "version": "0.86.0"
25
+ },
26
+ {
27
+ "changes": [
28
+ {
29
+ "kind": "changed",
30
+ "summary": "Include Neon in the typed built-in provider registry and configuration resolution",
31
+ "symbols": [
32
+ "buildClientProviders",
33
+ "resolveProviderClientConfiguration"
34
+ ]
35
+ },
36
+ {
37
+ "kind": "breaking",
38
+ "migration": {
39
+ "instruction": "Move createNeonProviderConfiguration results from customProviders.neon to providersConfiguration.neon. Neon is now a built-in Citra provider; credentials, scopes and offlineAccess inputs are unchanged.",
40
+ "manual": true
41
+ },
42
+ "summary": "Use the native Citra Neon provider for Auth configuration and linked-account refresh",
43
+ "symbols": [
44
+ "createNeonProviderConfiguration",
45
+ "neonProviderConfiguration"
46
+ ]
47
+ }
48
+ ],
49
+ "date": "2026-09-23",
50
+ "version": "0.85.0"
51
+ },
5
52
  {
6
53
  "changes": [
7
54
  {
package/dist/bun.js CHANGED
@@ -13754,6 +13754,32 @@ var providers = defineProviders({
13754
13754
  url: "https://nid.naver.com/oauth2.0/token"
13755
13755
  }
13756
13756
  },
13757
+ neon: {
13758
+ authorizationUrl: "https://oauth2.neon.tech/oauth2/auth",
13759
+ isOIDC: true,
13760
+ isRefreshable: true,
13761
+ PKCEMethod: "S256",
13762
+ profileRequest: {
13763
+ authIn: "header",
13764
+ encoding: "application/json",
13765
+ method: "GET",
13766
+ url: "https://oauth2.neon.tech/userinfo"
13767
+ },
13768
+ revocationRequest: {
13769
+ authIn: "body",
13770
+ encoding: "application/x-www-form-urlencoded",
13771
+ tokenParamName: "token",
13772
+ url: "https://oauth2.neon.tech/oauth2/revoke"
13773
+ },
13774
+ scopeRequired: true,
13775
+ subject: ["sub"],
13776
+ subjectType: "string",
13777
+ tokenRequest: {
13778
+ authIn: "body",
13779
+ encoding: "application/x-www-form-urlencoded",
13780
+ url: "https://oauth2.neon.tech/oauth2/token"
13781
+ }
13782
+ },
13757
13783
  notion: {
13758
13784
  authorizationUrl: "https://api.notion.com/v1/oauth/authorize",
13759
13785
  email: ["bot", "owner", "user", "person", "email"],
@@ -16892,6 +16918,27 @@ var toInvitation = (row) => ({
16892
16918
  });
16893
16919
  var createNeonOrganizationStore = (databaseUrl) => createPostgresOrganizationStore(createNeonDatabase(databaseUrl));
16894
16920
  var createPostgresOrganizationStore = (db) => ({
16921
+ acceptInvitation: async ({ now, tokenHash, userId, verifiedEmail }) => {
16922
+ const claimed = db.$with("claimed").as(db.update(organizationInvitationsTable).set({ accepted_at_ms: now, state: "accepted" }).where(and(eq(organizationInvitationsTable.token_hash, tokenHash), eq(organizationInvitationsTable.state, "pending"), gt3(organizationInvitationsTable.expires_at_ms, now), sql`lower(trim(${organizationInvitationsTable.email})) = ${verifiedEmail}`, exists(db.select().from(organizationsTable).where(eq(organizationsTable.organization_id, organizationInvitationsTable.organization_id))), notExists(db.select().from(organizationMembershipsTable).where(and(eq(organizationMembershipsTable.organization_id, organizationInvitationsTable.organization_id), eq(organizationMembershipsTable.user_id, userId), eq(organizationMembershipsTable.status, "suspended")))))).returning({
16923
+ organizationId: organizationInvitationsTable.organization_id,
16924
+ roles: organizationInvitationsTable.roles
16925
+ }));
16926
+ const [row] = await db.with(claimed).insert(organizationMembershipsTable).select(db.select({
16927
+ created_at_ms: sql`${now}`.as("created_at_ms"),
16928
+ organization_id: claimed.organizationId,
16929
+ roles: claimed.roles,
16930
+ status: sql`'active'`.as("status"),
16931
+ updated_at_ms: sql`${now}`.as("updated_at_ms"),
16932
+ user_id: sql`${userId}`.as("user_id")
16933
+ }).from(claimed)).onConflictDoUpdate({
16934
+ set: { user_id: userId },
16935
+ target: [
16936
+ organizationMembershipsTable.organization_id,
16937
+ organizationMembershipsTable.user_id
16938
+ ]
16939
+ }).returning();
16940
+ return row && row.status === "active" ? toMembership(row) : undefined;
16941
+ },
16895
16942
  deleteOrganization: async (organizationId) => {
16896
16943
  await db.delete(organizationsTable).where(eq(organizationsTable.organization_id, organizationId));
16897
16944
  },
@@ -18074,5 +18121,5 @@ export {
18074
18121
  runBunMigrations
18075
18122
  };
18076
18123
 
18077
- //# debugId=2CBFE7DC73F7997264756E2164756E21
18124
+ //# debugId=0AF087F2064BFFA264756E2164756E21
18078
18125
  //# sourceMappingURL=bun.js.map