Skip to content

Commit adc25bc

Browse files
committed
Add LDAP authentication provider and update request logger for enhanced logging
1 parent 6736d13 commit adc25bc

File tree

7 files changed

+401
-87
lines changed

7 files changed

+401
-87
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ As mentioned above, there are a few environment variables that can be used to co
5555
| SESSION_SECRET | The secret used to sign the session cookie | |
5656
| ACCESS_TOKEN_NAME | The name of the access token cookie | `_access_token` |
5757
| ACCESS_TOKEN_SECRET | The secret used to sign the access token cookie | `secret` |
58-
| ACCESS_TOKEN_EXPIRATION | The expiration time for the access token cookie | `15m` |
58+
| ACCESS_TOKEN_EXPIRATION | The expiration time for the access token cookie | `15m` |
5959
| REFRESH_TOKEN_NAME | The name of the refresh token cookie | `_refresh_token` |
6060
| REFRESH_TOKEN_SECRET | The secret used to sign the refresh token cookie | `refresh` |
6161
| REFRESH_TOKEN_EXPIRATION | The expiration time for the refresh token cookie | `7d` |
@@ -169,6 +169,18 @@ The Apple provider is used to authenticate users using Apple ID.
169169
> [!NOTE]
170170
> In order to set up this provider, you'll need to enroll in the Apple Developer Program. You can find more information [here](https://developer.apple.com/sign-in-with-apple/get-started/).
171171
172+
#### LDAP
173+
174+
The LDAP provider is used to authenticate users against an LDAP server.
175+
176+
| Variable | Description | Default |
177+
| ------------------ | ---------------------------------------- | ------- |
178+
| \_URL | The URL to the LDAP server | |
179+
| \_BIND_DN | The bind DN for the LDAP server | |
180+
| \_BIND_CREDENTIALS | The bind credentials for the LDAP server | |
181+
| \_SEARCH_BASE | The search base for the LDAP server | |
182+
| \_SEARCH_FILTER | The search filter for the LDAP server | |
183+
172184
## Contributing
173185

174186
Contributions are welcome, please read the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.

__tests__/providers/ldap.test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const { stop } = require("../../app");
2+
3+
jest.mock("passport-ldapauth");
4+
5+
describe("LDAP Authentication Strategy", () => {
6+
// Mock environment variables
7+
process.env.LDAP_LDAP_URL = "ldap://test-ldap";
8+
process.env.LDAP_LDAP_BIND_DN = "cn=admin,dc=example,dc=com";
9+
process.env.LDAP_LDAP_BIND_CREDENTIALS = "admin-password";
10+
process.env.LDAP_LDAP_SEARCH_BASE = "ou=users,dc=example,dc=com";
11+
process.env.LDAP_LDAP_SEARCH_FILTER = "(uid={{username}})";
12+
process.env.LDAP_LDAP_DISPLAY_NAME = "Test LDAP";
13+
process.env.LDAP_LDAP_ICON = "fas fa-user";
14+
const ldapProvider = require("../../src/providers/ldap");
15+
16+
it("should correctly configure the LDAP strategy", () => {
17+
const provider = ldapProvider("ldap", "LDAP");
18+
19+
expect(provider.name).toBe("ldap_ldap");
20+
expect(provider.type).toBe("ldap");
21+
expect(provider.params.server.url).toBe("ldap://test-ldap");
22+
expect(provider.params.server.bindDN).toBe("cn=admin,dc=example,dc=com");
23+
expect(provider.params.server.bindCredentials).toBe("admin-password");
24+
expect(provider.params.loginURL).toBe("/_ldap/ldap");
25+
expect(provider.params.callbackURL).toBe("/_ldap/ldap/callback");
26+
});
27+
28+
it("should correctly process user profile in verify callback", (done) => {
29+
const provider = ldapProvider("ldap", "LDAP");
30+
31+
const mockUser = {
32+
uid: "ldap123",
33+
displayName: "Test User",
34+
};
35+
36+
provider.verify(mockUser, (err, user) => {
37+
expect(err).toBeNull();
38+
expect(user).toEqual({
39+
id: "ldap123",
40+
strategy: "ldap_ldap",
41+
profile: mockUser,
42+
});
43+
done();
44+
});
45+
});
46+
});
47+
48+
afterAll(() => {
49+
stop();
50+
});

app.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const passport = require("./src/passport-setup");
99
const session = require("express-session");
1010
const strategies = require("./src/strategies");
1111
const createProviderRoutes = require("./src/dynamic-routes");
12+
// const helmet = require("helmet");
1213
const {
1314
ACCESS_TOKEN_NAME,
1415
REFRESH_TOKEN_NAME,
@@ -45,23 +46,27 @@ app.set("layout", "./layouts/page");
4546
app.set("view engine", "ejs");
4647
app.set("layout extractScripts", true);
4748

48-
// Middleware
49+
// Security Middleware
4950
// app.use(
5051
// helmet.contentSecurityPolicy({
5152
// directives: {
5253
// defaultSrc: ["'self'"],
5354
// scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", AUTH_HOST],
5455
// formAction: [AUTH_HOST],
5556
// },
56-
// }),
57+
// })
5758
// );
59+
60+
// Monitoring Middleware
5861
app.use(
5962
promBundle({
6063
includeMethod: true,
6164
includePath: true,
6265
metricsPath: `${PROMETHEUS_PREFIX}/metrics`,
6366
})
6467
);
68+
69+
// Other Middleware
6570
app.use(express.json());
6671
app.use(cookieParser());
6772
app.use(bodyParser.urlencoded({ extended: false }));
@@ -148,7 +153,8 @@ app.get(`${AUTH_PREFIX}/refresh`, async (req, res) => {
148153
: `${req.protocol}://${AUTH_HOST}${AUTH_PREFIX}/`,
149154
[{ name: ACCESS_TOKEN_NAME, value: token, options: COOKIE_CONFIG }]
150155
);
151-
} catch {
156+
} catch (error) {
157+
console.error("Error verifying refresh token:", error);
152158
removeGlobalCookies(
153159
req,
154160
res,
@@ -194,11 +200,9 @@ app.get(`${AUTH_PREFIX}/`, (req, res) => {
194200
.redirect(
195201
redirect_url
196202
? `${req.protocol}://${AUTH_HOST}${AUTH_PREFIX}/refresh?redirect_url=${redirect_url}`
197-
: `${
198-
req.protocol
199-
}://${AUTH_HOST}${AUTH_PREFIX}/refresh?redirect_url=${
200-
req.protocol
201-
}://${req.headers.host}${req.forwardedUri || ""}`
203+
: `${req.protocol
204+
}://${AUTH_HOST}${AUTH_PREFIX}/refresh?redirect_url=${req.protocol
205+
}://${req.headers.host}${req.forwardedUri || ""}`
202206
);
203207

204208
const decoded = jwt.verify(token, ACCESS_TOKEN_SECRET);
@@ -212,7 +216,8 @@ app.get(`${AUTH_PREFIX}/`, (req, res) => {
212216
longLivedTokens: LONG_LIVED_TOKENS,
213217
show_credit: !FORM_DISABLE_CREDITS,
214218
});
215-
} catch {
219+
} catch (error) {
220+
console.error("Error verifying access token:", error);
216221
req.session.redirect =
217222
req.query.redirect_url ||
218223
`${req.protocol}://${req.headers.host}${req.forwardedUri || ""}`;
@@ -253,4 +258,4 @@ process.on("SIGTERM", stop);
253258

254259
start();
255260

256-
module.exports = { app, server, start, stop };
261+
module.exports = { app, server, start, stop };

0 commit comments

Comments
 (0)