From 9d1d10596f8e3427daf91baa3e55ae05fa7d8bd5 Mon Sep 17 00:00:00 2001 From: Tim Aebi Date: Sat, 19 Aug 2017 11:45:26 +0200 Subject: [PATCH] #65: Set headers X-Remote-User and Remote-Groups --- doc/api_data.js | 976 +-------------------- doc/api_data.json | 976 +-------------------- doc/api_project.js | 16 +- doc/api_project.json | 16 +- example/nginx/nginx.conf | 4 +- src/server/endpoints.ts | 5 +- src/server/lib/routes/verify/get.ts | 5 +- test/unit/server/routes/verify/get.test.ts | 3 + 8 files changed, 15 insertions(+), 1986 deletions(-) diff --git a/doc/api_data.js b/doc/api_data.js index 2eacc2aaf..a63c5dbd7 100644 --- a/doc/api_data.js +++ b/doc/api_data.js @@ -1,975 +1 @@ -define({ "api": [ - { - "type": "get", - "url": "/", - "title": "First factor page", - "name": "Login", - "group": "Authentication", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "Content", - "description": "

The content of the first factor page.

" - } - ] - } - }, - "description": "

Serves the login page and create a create a cookie for the client.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication" - }, - { - "type": "get", - "url": "/logout", - "title": "Serves logout page", - "name": "Logout", - "group": "Authentication", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "redirect", - "description": "

Redirect to this URL when user is deauthenticated.

" - } - ] - } - }, - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "redirect", - "description": "

Redirect to the URL.

" - } - ] - } - }, - "description": "

Log out the user and redirect to the URL.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication" - }, - { - "type": "get", - "url": "/secondfactor", - "title": "Second factor page", - "name": "SecondFactor", - "group": "Authentication", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "Content", - "description": "

The content of second factor page.

" - } - ] - } - }, - "description": "

Serves the second factor page

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication" - }, - { - "type": "post", - "url": "/1stfactor", - "title": "Bind user against LDAP", - "name": "ValidateFirstFactor", - "group": "Authentication", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "username", - "description": "

User username.

" - }, - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "password", - "description": "

User password.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

1st factor is validated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "type": "none", - "optional": false, - "field": "error", - "description": "

1st factor is not validated.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Verify credentials against the LDAP.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/reset-password/request", - "title": "Finish password reset request", - "name": "FinishPasswordResetRequest", - "group": "PasswordReset", - "version": "1.0.0", - "description": "

Start password reset request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "identity_token", - "description": "

The one-time identity validation token provided in the email.

" - } - ] - } - }, - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "content", - "description": "

The content of the page.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/password-reset/request", - "title": "Request username", - "name": "ServePasswordResetPage", - "group": "PasswordReset", - "version": "1.0.0", - "description": "

Serve a page that requires the username.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/password-reset", - "title": "Set new password", - "name": "SetNewLDAPPassword", - "group": "PasswordReset", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "password", - "description": "

New password

" - } - ] - } - }, - "description": "

Set a new password for the user.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/password-reset/identity/start", - "title": "Start password reset request", - "name": "StartPasswordResetRequest", - "group": "PasswordReset", - "version": "1.0.0", - "description": "

Start password reset request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

Identity validation has been initiated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 400": [ - { - "group": "Error 400", - "optional": false, - "field": "InvalidIdentity", - "description": "

User identity is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/secondfactor/totp/identity/finish", - "title": "Finish TOTP registration identity validation", - "name": "FinishTOTPRegistration", - "group": "TOTP", - "version": "1.0.0", - "description": "

Serves the TOTP registration page that displays the secret. The secret is a QRCode and a base32 secret.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "TOTP", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "identity_token", - "description": "

The one-time identity validation token provided in the email.

" - } - ] - } - }, - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "content", - "description": "

The content of the page.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/secondfactor/totp/identity/start", - "title": "Start TOTP registration identity validation", - "name": "StartTOTPRegistration", - "group": "TOTP", - "version": "1.0.0", - "description": "

Initiates the identity validation

", - "filename": "src/server/endpoints.ts", - "groupTitle": "TOTP", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

Identity validation has been initiated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 400": [ - { - "group": "Error 400", - "optional": false, - "field": "InvalidIdentity", - "description": "

User identity is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/totp", - "title": "Complete TOTP authentication", - "name": "ValidateTOTPSecondFactor", - "group": "TOTP", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "token", - "description": "

TOTP token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "Redirect", - "description": "

to the URL that has been stored during last call to /verify.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "type": "none", - "optional": false, - "field": "error", - "description": "

TOTP token is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Verify TOTP token. The user is authenticated upon success.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "TOTP", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/u2f/sign", - "title": "Complete U2F authentication", - "name": "CompleteU2FAuthentication", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "Redirect", - "description": "

to the URL that has been stored during last call to /verify.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "type": "none", - "optional": false, - "field": "error", - "description": "

No authentication request has been provided.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Complete authentication request of the U2F device.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/secondfactor/u2f/register", - "title": "Complete U2F registration", - "name": "FinishU2FRegistration", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "Redirect", - "description": "

to the URL that has been stored during last call to /verify.

" - } - ] - } - }, - "description": "

Complete U2F registration request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "error": { - "fields": { - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/secondfactor/u2f/identity/start", - "title": "Start U2F registration identity validation", - "name": "RequestU2FRegistration", - "group": "U2F", - "version": "1.0.0", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

Identity validation has been initiated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 400": [ - { - "group": "Error 400", - "optional": false, - "field": "InvalidIdentity", - "description": "

User identity is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

This request issue an identity validation token for the user bound to the session. It sends a challenge to the email address set in the user LDAP entry. The user must visit the sent URL to complete the validation and continue the registration process.

" - }, - { - "type": "get", - "url": "/secondfactor/u2f/identity/finish", - "title": "Finish U2F registration identity validation", - "name": "ServeU2FRegistrationPage", - "group": "U2F", - "version": "1.0.0", - "description": "

Serves the U2F registration page that asks the user to touch the token of the U2F device.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "identity_token", - "description": "

The one-time identity validation token provided in the email.

" - } - ] - } - }, - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "content", - "description": "

The content of the page.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/api/u2f/sign_request", - "title": "Start U2F authentication", - "name": "StartU2FAuthentication", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "optional": false, - "field": "authentication_request", - "description": "

The U2F authentication request.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "type": "none", - "optional": false, - "field": "error", - "description": "

There is no key registered for user in session.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Initiate an authentication request using a U2F device.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/api/u2f/register_request", - "title": "Start U2F registration", - "name": "StartU2FRegistration", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "optional": false, - "field": "authentication_request", - "description": "

The U2F registration request.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "type": "none", - "optional": false, - "field": "error", - "description": "

Unexpected identity validation challenge.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Initiate a U2F device registration request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/verify", - "title": "Verify user authentication", - "name": "VerifyAuthentication", - "group": "Verification", - "version": "1.0.0", - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

The user is authenticated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "optional": false, - "field": "status", - "description": "

The user is not authenticated.

" - } - ] - } - }, - "description": "

Verify that the user is authenticated, i.e., the two factors have been validated

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Verification", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - } -] }); +define({ "api": [ { "type": "get", "url": "/", "title": "First factor page", "name": "Login", "group": "Authentication", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "Content", "description": "

The content of the first factor page.

" } ] } }, "description": "

Serves the login page and create a create a cookie for the client.

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication" }, { "type": "get", "url": "/logout", "title": "Serves logout page", "name": "Logout", "group": "Authentication", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "redirect", "description": "

Redirect to this URL when user is deauthenticated.

" } ] } }, "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "redirect", "description": "

Redirect to the URL.

" } ] } }, "description": "

Log out the user and redirect to the URL.

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication" }, { "type": "get", "url": "/secondfactor", "title": "Second factor page", "name": "SecondFactor", "group": "Authentication", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "Content", "description": "

The content of second factor page.

" } ] } }, "description": "

Serves the second factor page

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication" }, { "type": "post", "url": "/1stfactor", "title": "Bind user against LDAP", "name": "ValidateFirstFactor", "group": "Authentication", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "username", "description": "

User username.

" }, { "group": "Parameter", "type": "String", "optional": false, "field": "password", "description": "

User password.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

1st factor is validated.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "type": "none", "optional": false, "field": "error", "description": "

1st factor is not validated.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Verify credentials against the LDAP.

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/reset-password/request", "title": "Finish password reset request", "name": "FinishPasswordResetRequest", "group": "PasswordReset", "version": "1.0.0", "description": "

Start password reset request.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "identity_token", "description": "

The one-time identity validation token provided in the email.

" } ] } }, "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "content", "description": "

The content of the page.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/password-reset/request", "title": "Request username", "name": "ServePasswordResetPage", "group": "PasswordReset", "version": "1.0.0", "description": "

Serve a page that requires the username.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/api/password-reset", "title": "Set new password", "name": "SetNewLDAPPassword", "group": "PasswordReset", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "password", "description": "

New password

" } ] } }, "description": "

Set a new password for the user.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "get", "url": "/password-reset/identity/start", "title": "Start password reset request", "name": "StartPasswordResetRequest", "group": "PasswordReset", "version": "1.0.0", "description": "

Start password reset request.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

Identity validation has been initiated.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 400": [ { "group": "Error 400", "optional": false, "field": "InvalidIdentity", "description": "

User identity is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/secondfactor/totp/identity/finish", "title": "Finish TOTP registration identity validation", "name": "FinishTOTPRegistration", "group": "TOTP", "version": "1.0.0", "description": "

Serves the TOTP registration page that displays the secret. The secret is a QRCode and a base32 secret.

", "filename": "src/server/endpoints.ts", "groupTitle": "TOTP", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "identity_token", "description": "

The one-time identity validation token provided in the email.

" } ] } }, "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "content", "description": "

The content of the page.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/secondfactor/totp/identity/start", "title": "Start TOTP registration identity validation", "name": "StartTOTPRegistration", "group": "TOTP", "version": "1.0.0", "description": "

Initiates the identity validation

", "filename": "src/server/endpoints.ts", "groupTitle": "TOTP", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

Identity validation has been initiated.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 400": [ { "group": "Error 400", "optional": false, "field": "InvalidIdentity", "description": "

User identity is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "post", "url": "/api/totp", "title": "Complete TOTP authentication", "name": "ValidateTOTPSecondFactor", "group": "TOTP", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "token", "description": "

TOTP token.

" } ] } }, "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "Redirect", "description": "

to the URL that has been stored during last call to /verify.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "type": "none", "optional": false, "field": "error", "description": "

TOTP token is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Verify TOTP token. The user is authenticated upon success.

", "filename": "src/server/endpoints.ts", "groupTitle": "TOTP", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/api/u2f/sign", "title": "Complete U2F authentication", "name": "CompleteU2FAuthentication", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "Redirect", "description": "

to the URL that has been stored during last call to /verify.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "type": "none", "optional": false, "field": "error", "description": "

No authentication request has been provided.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Complete authentication request of the U2F device.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/api/secondfactor/u2f/register", "title": "Complete U2F registration", "name": "FinishU2FRegistration", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "Redirect", "description": "

to the URL that has been stored during last call to /verify.

" } ] } }, "description": "

Complete U2F registration request.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "error": { "fields": { "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/secondfactor/u2f/identity/start", "title": "Start U2F registration identity validation", "name": "RequestU2FRegistration", "group": "U2F", "version": "1.0.0", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

Identity validation has been initiated.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 400": [ { "group": "Error 400", "optional": false, "field": "InvalidIdentity", "description": "

User identity is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

This request issue an identity validation token for the user bound to the session. It sends a challenge to the email address set in the user LDAP entry. The user must visit the sent URL to complete the validation and continue the registration process.

" }, { "type": "get", "url": "/secondfactor/u2f/identity/finish", "title": "Finish U2F registration identity validation", "name": "ServeU2FRegistrationPage", "group": "U2F", "version": "1.0.0", "description": "

Serves the U2F registration page that asks the user to touch the token of the U2F device.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "identity_token", "description": "

The one-time identity validation token provided in the email.

" } ] } }, "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "content", "description": "

The content of the page.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/api/u2f/sign_request", "title": "Start U2F authentication", "name": "StartU2FAuthentication", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "optional": false, "field": "authentication_request", "description": "

The U2F authentication request.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "type": "none", "optional": false, "field": "error", "description": "

There is no key registered for user in session.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Initiate an authentication request using a U2F device.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "get", "url": "/api/u2f/register_request", "title": "Start U2F registration", "name": "StartU2FRegistration", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "optional": false, "field": "authentication_request", "description": "

The U2F registration request.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "type": "none", "optional": false, "field": "error", "description": "

Unexpected identity validation challenge.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Initiate a U2F device registration request.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "get", "url": "/verify", "title": "Verify user authentication", "name": "VerifyAuthentication", "group": "Verification", "version": "1.0.0", "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

The user is authenticated.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "optional": false, "field": "status", "description": "

The user is not authenticated.

" } ] } }, "description": "

Verify that the user is authenticated, i.e., the two factors have been validated. If the user is authenticated the response headers Remote-User and Remote-Groups are set. Remote-User contains the user id of the currently logged in user and Remote-Groups a comma separated list of assigned groups.

", "filename": "src/server/endpoints.ts", "groupTitle": "Verification", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } } ] }); diff --git a/doc/api_data.json b/doc/api_data.json index 527b67508..83564ce6e 100644 --- a/doc/api_data.json +++ b/doc/api_data.json @@ -1,975 +1 @@ -[ - { - "type": "get", - "url": "/", - "title": "First factor page", - "name": "Login", - "group": "Authentication", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "Content", - "description": "

The content of the first factor page.

" - } - ] - } - }, - "description": "

Serves the login page and create a create a cookie for the client.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication" - }, - { - "type": "get", - "url": "/logout", - "title": "Serves logout page", - "name": "Logout", - "group": "Authentication", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "redirect", - "description": "

Redirect to this URL when user is deauthenticated.

" - } - ] - } - }, - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "redirect", - "description": "

Redirect to the URL.

" - } - ] - } - }, - "description": "

Log out the user and redirect to the URL.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication" - }, - { - "type": "get", - "url": "/secondfactor", - "title": "Second factor page", - "name": "SecondFactor", - "group": "Authentication", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "Content", - "description": "

The content of second factor page.

" - } - ] - } - }, - "description": "

Serves the second factor page

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication" - }, - { - "type": "post", - "url": "/1stfactor", - "title": "Bind user against LDAP", - "name": "ValidateFirstFactor", - "group": "Authentication", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "username", - "description": "

User username.

" - }, - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "password", - "description": "

User password.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

1st factor is validated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "type": "none", - "optional": false, - "field": "error", - "description": "

1st factor is not validated.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Verify credentials against the LDAP.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Authentication", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/reset-password/request", - "title": "Finish password reset request", - "name": "FinishPasswordResetRequest", - "group": "PasswordReset", - "version": "1.0.0", - "description": "

Start password reset request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "identity_token", - "description": "

The one-time identity validation token provided in the email.

" - } - ] - } - }, - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "content", - "description": "

The content of the page.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/password-reset/request", - "title": "Request username", - "name": "ServePasswordResetPage", - "group": "PasswordReset", - "version": "1.0.0", - "description": "

Serve a page that requires the username.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/password-reset", - "title": "Set new password", - "name": "SetNewLDAPPassword", - "group": "PasswordReset", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "password", - "description": "

New password

" - } - ] - } - }, - "description": "

Set a new password for the user.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/password-reset/identity/start", - "title": "Start password reset request", - "name": "StartPasswordResetRequest", - "group": "PasswordReset", - "version": "1.0.0", - "description": "

Start password reset request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "PasswordReset", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

Identity validation has been initiated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 400": [ - { - "group": "Error 400", - "optional": false, - "field": "InvalidIdentity", - "description": "

User identity is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/secondfactor/totp/identity/finish", - "title": "Finish TOTP registration identity validation", - "name": "FinishTOTPRegistration", - "group": "TOTP", - "version": "1.0.0", - "description": "

Serves the TOTP registration page that displays the secret. The secret is a QRCode and a base32 secret.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "TOTP", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "identity_token", - "description": "

The one-time identity validation token provided in the email.

" - } - ] - } - }, - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "content", - "description": "

The content of the page.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/secondfactor/totp/identity/start", - "title": "Start TOTP registration identity validation", - "name": "StartTOTPRegistration", - "group": "TOTP", - "version": "1.0.0", - "description": "

Initiates the identity validation

", - "filename": "src/server/endpoints.ts", - "groupTitle": "TOTP", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

Identity validation has been initiated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 400": [ - { - "group": "Error 400", - "optional": false, - "field": "InvalidIdentity", - "description": "

User identity is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/totp", - "title": "Complete TOTP authentication", - "name": "ValidateTOTPSecondFactor", - "group": "TOTP", - "version": "1.0.0", - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "token", - "description": "

TOTP token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "Redirect", - "description": "

to the URL that has been stored during last call to /verify.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "type": "none", - "optional": false, - "field": "error", - "description": "

TOTP token is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Verify TOTP token. The user is authenticated upon success.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "TOTP", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/u2f/sign", - "title": "Complete U2F authentication", - "name": "CompleteU2FAuthentication", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "Redirect", - "description": "

to the URL that has been stored during last call to /verify.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "type": "none", - "optional": false, - "field": "error", - "description": "

No authentication request has been provided.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Complete authentication request of the U2F device.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "post", - "url": "/api/secondfactor/u2f/register", - "title": "Complete U2F registration", - "name": "FinishU2FRegistration", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 302": [ - { - "group": "Success 302", - "optional": false, - "field": "Redirect", - "description": "

to the URL that has been stored during last call to /verify.

" - } - ] - } - }, - "description": "

Complete U2F registration request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "error": { - "fields": { - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/secondfactor/u2f/identity/start", - "title": "Start U2F registration identity validation", - "name": "RequestU2FRegistration", - "group": "U2F", - "version": "1.0.0", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

Identity validation has been initiated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 400": [ - { - "group": "Error 400", - "optional": false, - "field": "InvalidIdentity", - "description": "

User identity is invalid.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

This request issue an identity validation token for the user bound to the session. It sends a challenge to the email address set in the user LDAP entry. The user must visit the sent URL to complete the validation and continue the registration process.

" - }, - { - "type": "get", - "url": "/secondfactor/u2f/identity/finish", - "title": "Finish U2F registration identity validation", - "name": "ServeU2FRegistrationPage", - "group": "U2F", - "version": "1.0.0", - "description": "

Serves the U2F registration page that asks the user to touch the token of the U2F device.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - }, - "parameter": { - "fields": { - "Parameter": [ - { - "group": "Parameter", - "type": "String", - "optional": false, - "field": "identity_token", - "description": "

The one-time identity validation token provided in the email.

" - } - ] - } - }, - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "type": "String", - "optional": false, - "field": "content", - "description": "

The content of the page.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "optional": false, - "field": "AccessDenied", - "description": "

Access is denied.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/api/u2f/sign_request", - "title": "Start U2F authentication", - "name": "StartU2FAuthentication", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "optional": false, - "field": "authentication_request", - "description": "

The U2F authentication request.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "type": "none", - "optional": false, - "field": "error", - "description": "

There is no key registered for user in session.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Initiate an authentication request using a U2F device.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/api/u2f/register_request", - "title": "Start U2F registration", - "name": "StartU2FRegistration", - "group": "U2F", - "version": "1.0.0", - "success": { - "fields": { - "Success 200": [ - { - "group": "Success 200", - "optional": false, - "field": "authentication_request", - "description": "

The U2F registration request.

" - } - ] - } - }, - "error": { - "fields": { - "Error 403": [ - { - "group": "Error 403", - "type": "none", - "optional": false, - "field": "error", - "description": "

Unexpected identity validation challenge.

" - } - ], - "Error 500": [ - { - "group": "Error 500", - "type": "String", - "optional": false, - "field": "error", - "description": "

Internal error message.

" - } - ] - } - }, - "description": "

Initiate a U2F device registration request.

", - "filename": "src/server/endpoints.ts", - "groupTitle": "U2F", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - }, - { - "type": "get", - "url": "/verify", - "title": "Verify user authentication", - "name": "VerifyAuthentication", - "group": "Verification", - "version": "1.0.0", - "success": { - "fields": { - "Success 204": [ - { - "group": "Success 204", - "optional": false, - "field": "status", - "description": "

The user is authenticated.

" - } - ] - } - }, - "error": { - "fields": { - "Error 401": [ - { - "group": "Error 401", - "optional": false, - "field": "status", - "description": "

The user is not authenticated.

" - } - ] - } - }, - "description": "

Verify that the user is authenticated, i.e., the two factors have been validated

", - "filename": "src/server/endpoints.ts", - "groupTitle": "Verification", - "header": { - "fields": { - "Header": [ - { - "group": "Header", - "type": "String", - "optional": false, - "field": "Cookie", - "description": "

Cookie containing "connect.sid", the user session token.

" - } - ] - } - } - } -] +[ { "type": "get", "url": "/", "title": "First factor page", "name": "Login", "group": "Authentication", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "Content", "description": "

The content of the first factor page.

" } ] } }, "description": "

Serves the login page and create a create a cookie for the client.

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication" }, { "type": "get", "url": "/logout", "title": "Serves logout page", "name": "Logout", "group": "Authentication", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "redirect", "description": "

Redirect to this URL when user is deauthenticated.

" } ] } }, "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "redirect", "description": "

Redirect to the URL.

" } ] } }, "description": "

Log out the user and redirect to the URL.

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication" }, { "type": "get", "url": "/secondfactor", "title": "Second factor page", "name": "SecondFactor", "group": "Authentication", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "Content", "description": "

The content of second factor page.

" } ] } }, "description": "

Serves the second factor page

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication" }, { "type": "post", "url": "/1stfactor", "title": "Bind user against LDAP", "name": "ValidateFirstFactor", "group": "Authentication", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "username", "description": "

User username.

" }, { "group": "Parameter", "type": "String", "optional": false, "field": "password", "description": "

User password.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

1st factor is validated.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "type": "none", "optional": false, "field": "error", "description": "

1st factor is not validated.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Verify credentials against the LDAP.

", "filename": "src/server/endpoints.ts", "groupTitle": "Authentication", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/reset-password/request", "title": "Finish password reset request", "name": "FinishPasswordResetRequest", "group": "PasswordReset", "version": "1.0.0", "description": "

Start password reset request.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "identity_token", "description": "

The one-time identity validation token provided in the email.

" } ] } }, "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "content", "description": "

The content of the page.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/password-reset/request", "title": "Request username", "name": "ServePasswordResetPage", "group": "PasswordReset", "version": "1.0.0", "description": "

Serve a page that requires the username.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/api/password-reset", "title": "Set new password", "name": "SetNewLDAPPassword", "group": "PasswordReset", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "password", "description": "

New password

" } ] } }, "description": "

Set a new password for the user.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "get", "url": "/password-reset/identity/start", "title": "Start password reset request", "name": "StartPasswordResetRequest", "group": "PasswordReset", "version": "1.0.0", "description": "

Start password reset request.

", "filename": "src/server/endpoints.ts", "groupTitle": "PasswordReset", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

Identity validation has been initiated.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 400": [ { "group": "Error 400", "optional": false, "field": "InvalidIdentity", "description": "

User identity is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/secondfactor/totp/identity/finish", "title": "Finish TOTP registration identity validation", "name": "FinishTOTPRegistration", "group": "TOTP", "version": "1.0.0", "description": "

Serves the TOTP registration page that displays the secret. The secret is a QRCode and a base32 secret.

", "filename": "src/server/endpoints.ts", "groupTitle": "TOTP", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "identity_token", "description": "

The one-time identity validation token provided in the email.

" } ] } }, "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "content", "description": "

The content of the page.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/secondfactor/totp/identity/start", "title": "Start TOTP registration identity validation", "name": "StartTOTPRegistration", "group": "TOTP", "version": "1.0.0", "description": "

Initiates the identity validation

", "filename": "src/server/endpoints.ts", "groupTitle": "TOTP", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

Identity validation has been initiated.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 400": [ { "group": "Error 400", "optional": false, "field": "InvalidIdentity", "description": "

User identity is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "post", "url": "/api/totp", "title": "Complete TOTP authentication", "name": "ValidateTOTPSecondFactor", "group": "TOTP", "version": "1.0.0", "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "token", "description": "

TOTP token.

" } ] } }, "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "Redirect", "description": "

to the URL that has been stored during last call to /verify.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "type": "none", "optional": false, "field": "error", "description": "

TOTP token is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Verify TOTP token. The user is authenticated upon success.

", "filename": "src/server/endpoints.ts", "groupTitle": "TOTP", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/api/u2f/sign", "title": "Complete U2F authentication", "name": "CompleteU2FAuthentication", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "Redirect", "description": "

to the URL that has been stored during last call to /verify.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "type": "none", "optional": false, "field": "error", "description": "

No authentication request has been provided.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Complete authentication request of the U2F device.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "post", "url": "/api/secondfactor/u2f/register", "title": "Complete U2F registration", "name": "FinishU2FRegistration", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 302": [ { "group": "Success 302", "optional": false, "field": "Redirect", "description": "

to the URL that has been stored during last call to /verify.

" } ] } }, "description": "

Complete U2F registration request.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "error": { "fields": { "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/secondfactor/u2f/identity/start", "title": "Start U2F registration identity validation", "name": "RequestU2FRegistration", "group": "U2F", "version": "1.0.0", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

Identity validation has been initiated.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 400": [ { "group": "Error 400", "optional": false, "field": "InvalidIdentity", "description": "

User identity is invalid.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

This request issue an identity validation token for the user bound to the session. It sends a challenge to the email address set in the user LDAP entry. The user must visit the sent URL to complete the validation and continue the registration process.

" }, { "type": "get", "url": "/secondfactor/u2f/identity/finish", "title": "Finish U2F registration identity validation", "name": "ServeU2FRegistrationPage", "group": "U2F", "version": "1.0.0", "description": "

Serves the U2F registration page that asks the user to touch the token of the U2F device.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } }, "parameter": { "fields": { "Parameter": [ { "group": "Parameter", "type": "String", "optional": false, "field": "identity_token", "description": "

The one-time identity validation token provided in the email.

" } ] } }, "success": { "fields": { "Success 200": [ { "group": "Success 200", "type": "String", "optional": false, "field": "content", "description": "

The content of the page.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "optional": false, "field": "AccessDenied", "description": "

Access is denied.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } } }, { "type": "get", "url": "/api/u2f/sign_request", "title": "Start U2F authentication", "name": "StartU2FAuthentication", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "optional": false, "field": "authentication_request", "description": "

The U2F authentication request.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "type": "none", "optional": false, "field": "error", "description": "

There is no key registered for user in session.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Initiate an authentication request using a U2F device.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "get", "url": "/api/u2f/register_request", "title": "Start U2F registration", "name": "StartU2FRegistration", "group": "U2F", "version": "1.0.0", "success": { "fields": { "Success 200": [ { "group": "Success 200", "optional": false, "field": "authentication_request", "description": "

The U2F registration request.

" } ] } }, "error": { "fields": { "Error 403": [ { "group": "Error 403", "type": "none", "optional": false, "field": "error", "description": "

Unexpected identity validation challenge.

" } ], "Error 500": [ { "group": "Error 500", "type": "String", "optional": false, "field": "error", "description": "

Internal error message.

" } ] } }, "description": "

Initiate a U2F device registration request.

", "filename": "src/server/endpoints.ts", "groupTitle": "U2F", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } }, { "type": "get", "url": "/verify", "title": "Verify user authentication", "name": "VerifyAuthentication", "group": "Verification", "version": "1.0.0", "success": { "fields": { "Success 204": [ { "group": "Success 204", "optional": false, "field": "status", "description": "

The user is authenticated.

" } ] } }, "error": { "fields": { "Error 401": [ { "group": "Error 401", "optional": false, "field": "status", "description": "

The user is not authenticated.

" } ] } }, "description": "

Verify that the user is authenticated, i.e., the two factors have been validated. If the user is authenticated the response headers Remote-User and Remote-Groups are set. Remote-User contains the user id of the currently logged in user and Remote-Groups a comma separated list of assigned groups.

", "filename": "src/server/endpoints.ts", "groupTitle": "Verification", "header": { "fields": { "Header": [ { "group": "Header", "type": "String", "optional": false, "field": "Cookie", "description": "

Cookie containing "connect.sid", the user session token.

" } ] } } } ] diff --git a/doc/api_project.js b/doc/api_project.js index 9b4ecf09d..bfb686bdb 100644 --- a/doc/api_project.js +++ b/doc/api_project.js @@ -1,15 +1 @@ -define({ - "title": "Authelia API documentation", - "name": "authelia", - "version": "2.1.3", - "description": "2FA Single Sign-On server for nginx using LDAP, TOTP and U2F", - "sampleUrl": false, - "defaultVersion": "0.0.0", - "apidoc": "0.3.0", - "generator": { - "name": "apidoc", - "time": "2017-06-11T20:41:36.025Z", - "url": "http://apidocjs.com", - "version": "0.17.6" - } -}); +define({ "title": "Authelia API documentation", "name": "authelia", "version": "3.2.0", "description": "2FA Single Sign-On server for nginx using LDAP, TOTP and U2F", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2017-08-19T09:41:58.170Z", "url": "http://apidocjs.com", "version": "0.17.6" } }); diff --git a/doc/api_project.json b/doc/api_project.json index b27e7e63e..aeb44a2e2 100644 --- a/doc/api_project.json +++ b/doc/api_project.json @@ -1,15 +1 @@ -{ - "title": "Authelia API documentation", - "name": "authelia", - "version": "2.1.3", - "description": "2FA Single Sign-On server for nginx using LDAP, TOTP and U2F", - "sampleUrl": false, - "defaultVersion": "0.0.0", - "apidoc": "0.3.0", - "generator": { - "name": "apidoc", - "time": "2017-06-11T20:41:36.025Z", - "url": "http://apidocjs.com", - "version": "0.17.6" - } -} +{ "title": "Authelia API documentation", "name": "authelia", "version": "3.2.0", "description": "2FA Single Sign-On server for nginx using LDAP, TOTP and U2F", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2017-08-19T09:41:58.170Z", "url": "http://apidocjs.com", "version": "0.17.6" } } diff --git a/example/nginx/nginx.conf b/example/nginx/nginx.conf index a91df4ce6..5c7520b1c 100644 --- a/example/nginx/nginx.conf +++ b/example/nginx/nginx.conf @@ -78,12 +78,10 @@ http { location = /secret.html { auth_request /auth_verify; - auth_request_set $user $upstream_http_x_remote_user; + auth_request_set $user $upstream_http_remote_user; proxy_set_header X-Forwarded-User $user; auth_request_set $groups $upstream_http_remote_groups; proxy_set_header Remote-Groups $groups; - auth_request_set $expiry $upstream_http_remote_expiry; - proxy_set_header Remote-Expiry $expiry; } } } diff --git a/src/server/endpoints.ts b/src/server/endpoints.ts index 7412aa967..852c9a79d 100644 --- a/src/server/endpoints.ts +++ b/src/server/endpoints.ts @@ -274,7 +274,10 @@ export const SECOND_FACTOR_GET = "/secondfactor"; * @apiError (Error 401) status The user is not authenticated. * * @apiDescription Verify that the user is authenticated, i.e., the two - * factors have been validated + * factors have been validated. + * If the user is authenticated the response headers Remote-User and Remote-Groups + * are set. Remote-User contains the user id of the currently logged in user and Remote-Groups + * a comma separated list of assigned groups. */ export const VERIFY_GET = "/verify"; diff --git a/src/server/lib/routes/verify/get.ts b/src/server/lib/routes/verify/get.ts index 59d06387b..3449ebdab 100644 --- a/src/server/lib/routes/verify/get.ts +++ b/src/server/lib/routes/verify/get.ts @@ -1,9 +1,7 @@ -import { Winston } from "winston"; import objectPath = require("object-path"); import BluebirdPromise = require("bluebird"); import express = require("express"); -import { AccessController } from "../../access_control/AccessController"; import exceptions = require("../../Exceptions"); import winston = require("winston"); import AuthenticationValidator = require("../../AuthenticationValidator"); @@ -35,6 +33,9 @@ function verify_filter(req: express.Request, res: express.Response): BluebirdPro if (!authSession.first_factor || !authSession.second_factor) return BluebirdPromise.reject(new exceptions.AccessDeniedError("First or second factor not validated")); + res.setHeader("Remote-User", username); + res.setHeader("Remote-Groups", groups.join(",")); + return BluebirdPromise.resolve(); }); } diff --git a/test/unit/server/routes/verify/get.test.ts b/test/unit/server/routes/verify/get.test.ts index 65cb5ab32..6ba9ce2eb 100644 --- a/test/unit/server/routes/verify/get.test.ts +++ b/test/unit/server/routes/verify/get.test.ts @@ -41,9 +41,12 @@ describe("test authentication token verification", function () { authSession.first_factor = true; authSession.second_factor = true; authSession.userid = "myuser"; + authSession.groups = ["mygroup", "othergroup"]; return VerifyGet.default(req as express.Request, res as any) .then(function () { + sinon.assert.calledWithExactly(res.setHeader, "Remote-User", "myuser"); + sinon.assert.calledWithExactly(res.setHeader, "Remote-Groups", "mygroup,othergroup"); assert.equal(204, res.status.getCall(0).args[0]); }); });