Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ed6bee1
feat(den): support Entra SSO auto-join
pascalandr Jun 10, 2026
886f297
fix(den): clean invitation placeholders after auto-join
pascalandr Jun 10, 2026
199f36b
fix(den): reconcile invitations on Entra auto-join
pascalandr Jun 10, 2026
a7d58e2
fix(den): ignore expired invites during Entra reconciliation
pascalandr Jun 10, 2026
30826c4
fix(den): clean expired Entra invite placeholders
pascalandr Jun 10, 2026
4cfda2e
fix(den): reconcile Entra invites before member hooks
pascalandr Jun 10, 2026
7e7ed0d
fix(den): preserve organization member lifecycle fields
pascalandr Jun 10, 2026
772702a
fix(den): keep pending invite members in org context
pascalandr Jun 10, 2026
fbb6d24
fix(den): expose Microsoft SSO in Den Web
pascalandr Jun 10, 2026
f0199f0
fix(den): gate Entra auto-join seat additions
pascalandr Jun 10, 2026
db5d193
fix(den): complete Entra SSO lifecycle coverage
pascalandr Jun 10, 2026
c05e152
fix(den): sync billing when invite placeholders clear
pascalandr Jun 10, 2026
a92acc8
fix(den): normalize Entra invite grant edges
pascalandr Jun 11, 2026
bda6aa4
fix(den): clear expired invite seat reservations
pascalandr Jun 11, 2026
0fef86b
fix(den): preserve Entra org context compatibility
pascalandr Jun 11, 2026
05a7ee4
fix(den): normalize Entra group identifiers
pascalandr Jun 11, 2026
323028e
Merge remote-tracking branch 'upstream/dev' into work/resolve-2174
pascalandr Jun 14, 2026
2593f41
Merge remote-tracking branch 'upstream/dev' into work/resolve-2174
pascalandr Jun 16, 2026
00e0310
fix(den): preserve Entra roles without group claims
pascalandr Jun 16, 2026
9af510b
Merge remote-tracking branch 'upstream/dev' into pr/entra-sso-auto-jo…
pascalandr Jun 16, 2026
df89ca6
fix(den): mark auth provider discovery public
pascalandr Jun 16, 2026
04578a1
Merge remote-tracking branch 'upstream/dev' into pr/entra-sso-auto-jo…
pascalandr Jun 18, 2026
50e88bf
fix(den): harden Entra and MCP role sync
pascalandr Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion ee/apps/den-api/src/auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getInitialActiveOrganizationIdForUser } from "./active-organization.js";
import { db } from "./db.js";
import { isEntraSsoEnabled, mapEntraProfileToUser, normalizeEntraTenantId } from "./entra-sso.js";
import { env } from "./env.js";
import { deriveDenMcpResource } from "./mcp/resource.js";
import { getDenAuthIssuer, getDenJwtOptions } from "./mcp/jwt-policy.js";
Expand Down Expand Up @@ -42,6 +43,7 @@ import {
ORGANIZATION_SAML_REQUIRE_TIMESTAMPS,
} from "./sso-saml-policy.js";
import {
ensureEntraSsoMembershipForAccount,
getOrganizationContextForUser,
seedDefaultOrganizationRoles,
validateOrganizationMemberRemovalForHook,
Expand Down Expand Up @@ -117,6 +119,18 @@ const socialProviders = {
},
}
: {}),
...(isEntraSsoEnabled(env.entra)
? {
microsoft: {
clientId: env.entra.clientId!,
clientSecret: env.entra.clientSecret!,
tenantId: normalizeEntraTenantId(env.entra.tenantId),
authority: "https://login.microsoftonline.com",
scope: ["openid", "profile", "email"],
mapProfileToUser: mapEntraProfileToUser,
},
}
: {}),
};

function hasRole(roleValue: string, roleName: string) {
Expand Down Expand Up @@ -155,6 +169,10 @@ function buildInvitationLink(invitationId: string) {
).toString();
}

export function getSignUpEmailRateLimitMax(devMode = env.devMode) {
return devMode ? 100 : 3;
}

function hasMcpScope(scopes: readonly string[]) {
return scopes.some((scope) => scope.startsWith("mcp:"));
}
Expand Down Expand Up @@ -224,6 +242,30 @@ export const auth = betterAuth({
freshAge: 15 * 60,
},
databaseHooks: {
account: {
create: {
after: async (account) => {
if (account.providerId === "microsoft") {
await ensureEntraSsoMembershipForAccount({
idToken: account.idToken,
providerId: account.providerId,
userId: normalizeDenTypeId("user", account.userId),
});
}
},
},
update: {
after: async (account) => {
if (account.providerId === "microsoft") {
await ensureEntraSsoMembershipForAccount({
idToken: account.idToken,
providerId: account.providerId,
userId: normalizeDenTypeId("user", account.userId),
});
}
},
},
},
member: {
delete: {
before: async (member: AuthMemberHookRow) => {
Expand Down Expand Up @@ -369,7 +411,7 @@ export const auth = betterAuth({
},
"/sign-up/email": {
window: 3600,
max: env.devMode ? 100 : 5,
max: getSignUpEmailRateLimitMax(),
},
"/email-otp/send-verification-otp": {
window: 3600,
Expand Down
Loading