diff --git a/src/env.js b/src/env.js index 8d0c642d934..d4354b4689b 100644 --- a/src/env.js +++ b/src/env.js @@ -4,6 +4,8 @@ const { createEnv } = require('@t3-oss/env-nextjs'); const trueStrings = ['1', 't', 'T', 'TRUE', 'true', 'True']; const falseStrings = ['0', 'f', 'F', 'FALSE', 'false', 'False']; +const ldapSearchScope = z.enum(['base', 'one', 'sub']).default('base'); + const zodParsedBoolean = () => z .enum([...trueStrings, ...falseStrings]) @@ -52,6 +54,7 @@ const env = createEnv({ AUTH_LDAP_BIND_DN: z.string(), AUTH_LDAP_BIND_PASSWORD: z.string(), AUTH_LDAP_BASE: z.string(), + AUTH_LDAP_SEARCH_SCOPE: z.enum(['base', 'one', 'sub']).default('base'), AUTH_LDAP_USERNAME_ATTRIBUTE: z.string().default('uid'), AUTH_LDAP_GROUP_CLASS: z.string().default('groupOfUniqueNames'), AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE: z.string().default('member'), @@ -115,6 +118,7 @@ const env = createEnv({ AUTH_LDAP_BIND_DN: process.env.AUTH_LDAP_BIND_DN, AUTH_LDAP_BIND_PASSWORD: process.env.AUTH_LDAP_BIND_PASSWORD, AUTH_LDAP_BASE: process.env.AUTH_LDAP_BASE, + AUTH_LDAP_SEARCH_SCOPE: process.env.AUTH_LDAP_SEARCH_SCOPE?.toLowerCase(), AUTH_LDAP_USERNAME_ATTRIBUTE: process.env.AUTH_LDAP_USERNAME_ATTRIBUTE, AUTH_LDAP_GROUP_CLASS: process.env.AUTH_LDAP_GROUP_CLASS, AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE: process.env.AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE, diff --git a/src/utils/auth/ldap.ts b/src/utils/auth/ldap.ts index 91d0761b1e6..879e0ccd8ab 100644 --- a/src/utils/auth/ldap.ts +++ b/src/utils/auth/ldap.ts @@ -20,8 +20,8 @@ type InferrableSearchOptions< type SearchResultIndex = Attributes extends string ? Attributes : Attributes extends readonly string[] - ? Attributes[number] - : string; + ? Attributes[number] + : string; type SearchResult< Attributes extends AttributeConstraint, @@ -101,11 +101,14 @@ export default Credentials({ const ldapUser = ( await ldapSearch(client, env.AUTH_LDAP_BASE, { filter: `(uid=${data.name})`, + scope: env.AUTH_LDAP_SEARCH_SCOPE, // as const for inference attributes: ['uid', 'mail'] as const, }) )[0]; + if (!ldapUser) throw new Error('User not found in LDAP'); + await ldapLogin(ldapUser.dn, data.password).then((client) => client.destroy()); const userGroups = ( @@ -113,6 +116,7 @@ export default Credentials({ filter: `(&(objectclass=${env.AUTH_LDAP_GROUP_CLASS})(${ env.AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE }=${ldapUser[env.AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE as 'dn' | 'uid']}))`, + scope: env.AUTH_LDAP_SEARCH_SCOPE, // as const for inference attributes: 'cn', })