[PR #7886] refactor: rewrite organization plugin (pt6) #15858

Open
opened 2026-04-13 10:16:07 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7886
Author: @ping-maxwell
Created: 2/10/2026
Status: 🔄 Open

Base: mainHead: refactor/org-rewrite-part6


📝 Commits (10+)

📊 Changes

230 files changed (+29167 additions, -16621 deletions)

View changed files

📝 docs/content/docs/plugins/organization-old.mdx (+0 -0)
docs/content/docs/plugins/organization/access-control.mdx (+85 -0)
docs/content/docs/plugins/organization/active-organizations.mdx (+5 -0)
docs/content/docs/plugins/organization/dynamic-access-control.mdx (+8 -0)
docs/content/docs/plugins/organization/index.mdx (+109 -0)
docs/content/docs/plugins/organization/invitations.mdx (+497 -0)
docs/content/docs/plugins/organization/members.mdx (+347 -0)
docs/content/docs/plugins/organization/organization-identifiers.mdx (+113 -0)
docs/content/docs/plugins/organization/organizations.mdx (+410 -0)
docs/content/docs/plugins/organization/teams.mdx (+791 -0)
📝 e2e/adapter/package.json (+1 -0)
📝 e2e/adapter/test/adapter-factory/basic.ts (+7 -7)
📝 e2e/adapter/test/adapter-factory/package.json (+2 -1)
📝 e2e/adapter/test/drizzle-adapter/package.json (+1 -0)
📝 e2e/adapter/test/kysely-adapter/adapter.kysely.pg.test.ts (+1 -1)
📝 e2e/adapter/test/kysely-adapter/package.json (+1 -0)
📝 e2e/adapter/test/memory-adapter/package.json (+1 -0)
📝 e2e/adapter/test/mongo-adapter/package.json (+1 -0)
📝 e2e/adapter/test/prisma-adapter/package.json (+1 -0)
📝 e2e/smoke/test/fixtures/tsconfig-declaration/package.json (+1 -0)

...and 80 more files

📄 Description

Organization Rewrite (part 6)

This PR is the organization plugin rewrite, the goal is to restructure the organization plugin code in both file structure and code cleanness. This rewrite will also include new features and minor performance improvements in specific areas.

PRs:

Todo

  • New Featurs
    • defaultOrganizationIdField support
    • Disable slug on organizations
    • Get organization endpoint
    • Get team endpoint
    • Documentation rewrite + sub-page support
    • Enable slug on teams
    • Additional fields support for teamMember
    • Create org on sign-up
    • Functionality to get invitation URL without sending email (even if sendInvitation) is defined.
    • Accept invitation should return organization details
    • add ctx to all team hooks
    • Support defaultTeamIdField for team addon.
    • Update Stripe plugin to use the new org functionality.
    • Change activeOrganizationId in session to be activeOrganization json obj to store metadata.
    • Make invitations work via user ID or email addresses.
    • Introduce organization privacy features, such as the ability to hide member emails in list-member related endpoints and such.
    • Allow passing roles to createInvitation, so that when the user accepts an invitation, they can be assigned those roles.
      • Consider permissions, the invitation creator is not allowed to assign roles with permissions higher level than they are.
    • Dynamic access control:
      • Prevent creating a role with “” as the role name
      • Need to make role in member table to start storing the role ID instead of the role's name.
        • This way updating the role via dynamic ac wouldn’t require updating every member’s role .
        • Same with deleting a role. However we still need to update every member’s role to go to a fallback role if their current role is being deleted.
        • The field will store both IDs and role-name based on if the role was a hard-coded role or a dynamic AC role. All default/hard-coded roles will remain as the role name in the field, but dynamic AC roles will be stored as roleId.
  • Endpoints
    • Organizations
      • Check organization slug
      • Create org
      • Delete org
      • Get full org
      • Get org
      • List orgs (+pagination support)
      • Set active org
      • Update org
    • Invitations
      • Accept invitation
      • Create invitation
      • Reject invitation
      • Cancel invitation
      • Get invitation
      • List invitation (+pagination support)
      • List user invitations (+pagination support)
    • Members
      • Add member
      • Remove member
      • Update member role
      • Get active member
      • Leave organization
      • List members (+pagination support)
      • Get active member role
    • Teams
      • Create team
      • Remove team
      • Get team
      • Update team
      • List organization teams (+pagination support)
      • Set active team
      • List user teams (+pagination support)
      • List team members (+pagination support)
      • Add team member
      • Remove team member
    • Dynamic Access Control
      • Create org role
      • Delete org role
      • List org roles (+pagination support)
      • Get org role
      • Update org role

Closes

https://github.com/better-auth/better-auth/issues/1247
#1849
#6038
https://github.com/better-auth/better-auth/issues/6662
https://github.com/better-auth/better-auth/pull/8931
... and more.


Summary by cubic

Ships Organization v2 as a standalone @better-auth/organization plugin with RBAC, Teams, dynamic access control, and full org/member/invitation APIs. Removes all org code from better-auth, updates imports/tests across packages, streamlines API key authorization, and adds new docs with a split sidebar.

  • New Features

    • Standalone package with client/addons: organizationClient, teamsClient, dynamicAccessControlClient.
    • Dynamic Access Control: createRole endpoint with tests; in-memory role cache; hasPermission supports single/multiple permissions; configurable role schema and error codes.
    • Teams addon: default team creation, invitation team validation, set active team on accept, remove member from all teams; slugs/limits with helpers.
    • Identifiers: defaultOrganizationIdField/defaultTeamIdField; branded RealOrganizationId/RealTeamId types and resolvers.
    • Docs: “Organization v2” pages (Organizations, Members, Invitations, Roles & Permissions, Dynamic AC, Active Orgs, Identifiers, Teams) with sidebar split and “Organization (old)” preserved.
  • Refactors

    • Core removal: all org code and client re-exports deleted from better-auth; adapters/CLI/oauth/e2e/tests now import @better-auth/organization.
    • API keys: permission check uses plugin hasPermission with role+action and org options (no ctx/orgId).
    • Endpoint/schema: safer deep-merge with deep copy; improved options inference; stronger additional-fields inference (handles empty and string-indexed shapes); filtered outputs for returned:false.
    • Adapters/types: new org/team adapters; org counting via member table; skip slug unique check if unchanged; fixed org metadata parsing; set/list active org endpoints.

Written for commit 8fe71336fe. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7886 **Author:** [@ping-maxwell](https://github.com/ping-maxwell) **Created:** 2/10/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `refactor/org-rewrite-part6` --- ### 📝 Commits (10+) - [`3d34ee3`](https://github.com/better-auth/better-auth/commit/3d34ee3e93035f5dfa83e23a2ded5f921a0359ad) wip - [`84d94a4`](https://github.com/better-auth/better-auth/commit/84d94a47c47dbfb00a6dfae7bd708a6a204fc68c) Update build-endpoint-schema.ts - [`bd84663`](https://github.com/better-auth/better-auth/commit/bd846631166f675e88be8f1dd3be21ee10be529f) update: improve build-endpoint-schema - [`9662e67`](https://github.com/better-auth/better-auth/commit/9662e674b4eaf6ad123c649255d5269fc95cbe94) Merge branch 'canary' into feat/org-rewrite - [`e50272b`](https://github.com/better-auth/better-auth/commit/e50272bb8672386f01097d6e96fa3e1b57a19aa7) fix: count-org adapter function to use member table - [`c025cf7`](https://github.com/better-auth/better-auth/commit/c025cf7136bec34a7ccf4ad9bb4264a4ea47be2d) Merge branch 'feat/org-rewrite' of https://github.com/ping-maxwell/better-auth into feat/org-rewrite - [`93a0670`](https://github.com/better-auth/better-auth/commit/93a0670f6f679fb4f76a3cc8967166ab602ba16f) Merge branch 'canary' into feat/org-rewrite - [`15bba08`](https://github.com/better-auth/better-auth/commit/15bba08f059d42c488c81f5050896a347e0c6282) update: create-org first-stage completed - [`36e975f`](https://github.com/better-auth/better-auth/commit/36e975f50b997711e990860fc066902ac84fe50b) Update build-endpoint-schema.ts - [`3cba580`](https://github.com/better-auth/better-auth/commit/3cba5809aec688ceaf6d81b7f37293c1f1818665) fix: create deep copy to avoid deep mutation ### 📊 Changes **230 files changed** (+29167 additions, -16621 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/organization-old.mdx` (+0 -0) ➕ `docs/content/docs/plugins/organization/access-control.mdx` (+85 -0) ➕ `docs/content/docs/plugins/organization/active-organizations.mdx` (+5 -0) ➕ `docs/content/docs/plugins/organization/dynamic-access-control.mdx` (+8 -0) ➕ `docs/content/docs/plugins/organization/index.mdx` (+109 -0) ➕ `docs/content/docs/plugins/organization/invitations.mdx` (+497 -0) ➕ `docs/content/docs/plugins/organization/members.mdx` (+347 -0) ➕ `docs/content/docs/plugins/organization/organization-identifiers.mdx` (+113 -0) ➕ `docs/content/docs/plugins/organization/organizations.mdx` (+410 -0) ➕ `docs/content/docs/plugins/organization/teams.mdx` (+791 -0) 📝 `e2e/adapter/package.json` (+1 -0) 📝 `e2e/adapter/test/adapter-factory/basic.ts` (+7 -7) 📝 `e2e/adapter/test/adapter-factory/package.json` (+2 -1) 📝 `e2e/adapter/test/drizzle-adapter/package.json` (+1 -0) 📝 `e2e/adapter/test/kysely-adapter/adapter.kysely.pg.test.ts` (+1 -1) 📝 `e2e/adapter/test/kysely-adapter/package.json` (+1 -0) 📝 `e2e/adapter/test/memory-adapter/package.json` (+1 -0) 📝 `e2e/adapter/test/mongo-adapter/package.json` (+1 -0) 📝 `e2e/adapter/test/prisma-adapter/package.json` (+1 -0) 📝 `e2e/smoke/test/fixtures/tsconfig-declaration/package.json` (+1 -0) _...and 80 more files_ </details> ### 📄 Description ## Organization Rewrite (part 6) This PR is the organization plugin rewrite, the goal is to restructure the organization plugin code in both file structure and code cleanness. This rewrite will also include new features and minor performance improvements in specific areas. ### PRs: * [part 1](https://github.com/better-auth/better-auth/pull/7251) * [part 2](https://github.com/better-auth/better-auth/pull/7544) * [part 3](https://github.com/better-auth/better-auth/pull/7591) * [part 4](https://github.com/better-auth/better-auth/pull/7601) * [part 5](https://github.com/better-auth/better-auth/pull/7628) * [part 6](https://github.com/better-auth/better-auth/pull/7886) - You're here ### Todo - [ ] New Featurs - [x] `defaultOrganizationIdField` support - [x] Disable slug on organizations - [x] Get organization endpoint - [x] Get team endpoint - [x] Documentation rewrite + sub-page support - [x] Enable slug on teams - [x] Additional fields support for `teamMember` - [x] Create org on sign-up - [x] Functionality to get invitation URL without sending email (even if `sendInvitation`) is defined. - [x] Accept invitation should return organization details - [x] add `ctx` to all team hooks - [x] Support `defaultTeamIdField` for team addon. - [x] Update Stripe plugin to use the new org functionality. - [ ] Change `activeOrganizationId` in `session` to be `activeOrganization` json obj to store metadata. - [ ] Make invitations work via **user ID** or email addresses. - [ ] Introduce organization privacy features, such as the ability to hide member emails in list-member related endpoints and such. - [ ] Allow passing `roles` to `createInvitation`, so that when the user accepts an invitation, they can be assigned those roles. - Consider permissions, the invitation creator is not allowed to assign roles with permissions higher level than they are. - [ ] Dynamic access control: - [ ] Prevent creating a role with `“”` as the role name - [ ] Need to make `role` in member table to start storing the role ID instead of the role's name. - This way updating the role via dynamic ac wouldn’t require updating every member’s `role` . - Same with deleting a role. However we still need to update every member’s `role` to go to a fallback role if their current role is being deleted. - The field will store both IDs and role-name based on if the role was a hard-coded role or a dynamic AC role. All default/hard-coded roles will remain as the role name in the field, but dynamic AC roles will be stored as roleId. - [ ] Endpoints - Organizations - [x] Check organization slug - [x] Create org - [x] Delete org - [x] Get full org - [x] Get org - [x] List orgs (+pagination support) - [x] Set active org - [x] Update org - Invitations - [x] Accept invitation - [x] Create invitation - [x] Reject invitation - [x] Cancel invitation - [x] Get invitation - [x] List invitation (+pagination support) - [x] List user invitations (+pagination support) - Members - [x] Add member - [x] Remove member - [x] Update member role - [x] Get active member - [x] Leave organization - [x] List members (+pagination support) - [x] Get active member role - Teams - [x] Create team - [x] Remove team - [x] Get team - [x] Update team - [x] List organization teams (+pagination support) - [x] Set active team - [x] List user teams (+pagination support) - [x] List team members (+pagination support) - [x] Add team member - [x] Remove team member - Dynamic Access Control - [x] Create org role - [ ] Delete org role - [ ] List org roles (+pagination support) - [ ] Get org role - [ ] Update org role ## Closes https://github.com/better-auth/better-auth/issues/1247 #1849 #6038 https://github.com/better-auth/better-auth/issues/6662 https://github.com/better-auth/better-auth/pull/8931 ... and more. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Ships Organization v2 as a standalone @better-auth/organization plugin with RBAC, Teams, dynamic access control, and full org/member/invitation APIs. Removes all org code from better-auth, updates imports/tests across packages, streamlines API key authorization, and adds new docs with a split sidebar. - **New Features** - Standalone package with client/addons: organizationClient, teamsClient, dynamicAccessControlClient. - Dynamic Access Control: createRole endpoint with tests; in-memory role cache; hasPermission supports single/multiple permissions; configurable role schema and error codes. - Teams addon: default team creation, invitation team validation, set active team on accept, remove member from all teams; slugs/limits with helpers. - Identifiers: defaultOrganizationIdField/defaultTeamIdField; branded RealOrganizationId/RealTeamId types and resolvers. - Docs: “Organization v2” pages (Organizations, Members, Invitations, Roles & Permissions, Dynamic AC, Active Orgs, Identifiers, Teams) with sidebar split and “Organization (old)” preserved. - **Refactors** - Core removal: all org code and client re-exports deleted from better-auth; adapters/CLI/oauth/e2e/tests now import @better-auth/organization. - API keys: permission check uses plugin hasPermission with role+action and org options (no ctx/orgId). - Endpoint/schema: safer deep-merge with deep copy; improved options inference; stronger additional-fields inference (handles empty and string-indexed shapes); filtered outputs for returned:false. - Adapters/types: new org/team adapters; org counting via member table; skip slug unique check if unchanged; fixed org metadata parsing; set/list active org endpoints. <sup>Written for commit 8fe71336febc58f26aaa6505f218b99918d4caf8. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 10:16:07 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#15858