Skip to content

Commit c243bf6

Browse files
committed
feat: use 303 See Other HTTP response status code for built in redirects
1 parent f3c1d5f commit c243bf6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+235
-226
lines changed

certification/fapi/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ if (process.env.NODE_ENV === 'production') {
252252
default:
253253
}
254254
} else if (ctx.method === 'GET' || ctx.method === 'HEAD') {
255+
ctx.status = 303;
255256
ctx.redirect(ctx.href.replace(/^http:\/\//i, 'https://'));
256257
} else {
257258
ctx.body = {

certification/oidc/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ let server;
114114
default:
115115
}
116116
} else if (ctx.method === 'GET' || ctx.method === 'HEAD') {
117+
ctx.status = 303;
117118
ctx.redirect(ctx.href.replace(/^http:\/\//i, 'https://'));
118119
} else {
119120
ctx.body = {

example/koa.js

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ if (process.env.NODE_ENV === 'production') {
3232
if (ctx.secure) {
3333
await next();
3434
} else if (ctx.method === 'GET' || ctx.method === 'HEAD') {
35+
ctx.status = 303;
3536
ctx.redirect(ctx.href.replace(/^http:\/\//i, 'https://'));
3637
} else {
3738
ctx.body = {

example/routes/koa.js

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ module.exports = (provider) => {
126126
ctx.cookies.set('google.state', state, { path, sameSite: 'strict' });
127127
ctx.cookies.set('google.nonce', nonce, { path, sameSite: 'strict' });
128128

129+
ctx.status = 303;
129130
return ctx.redirect(ctx.google.authorizationUrl({
130131
state, nonce, scope: 'openid email profile',
131132
}));

example/standalone.js

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ let server;
3535
if (ctx.secure) {
3636
await next();
3737
} else if (ctx.method === 'GET' || ctx.method === 'HEAD') {
38+
ctx.status = 303;
3839
ctx.redirect(ctx.href.replace(/^http:\/\//i, 'https://'));
3940
} else {
4041
ctx.body = {

lib/actions/authorization/interactions.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ module.exports = async function interactions(resumeRouteName, ctx, next) {
8686
throw new errors.CustomOIDCProviderError(failedCheck.error, failedCheck.error_description);
8787
}
8888
} catch (err) {
89-
const code = /^(code|device)_/.test(oidc.route) ? 400 : 302;
89+
const code = /^(code|device)_/.test(oidc.route) ? 400 : 303;
9090
err.status = code;
9191
err.statusCode = code;
9292
err.expose = true;
@@ -148,5 +148,6 @@ module.exports = async function interactions(resumeRouteName, ctx, next) {
148148
);
149149

150150
oidc.provider.emit('interaction.started', ctx, prompt);
151+
ctx.status = 303;
151152
ctx.redirect(destination);
152153
};

lib/actions/end_session.js

+1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ module.exports = {
210210

211211
ctx.oidc.provider.emit('end_session.success', ctx);
212212

213+
ctx.status = 303;
213214
ctx.redirect(uri);
214215

215216
await next();

lib/provider.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class Provider extends events.EventEmitter {
260260
async interactionFinished(req, res, result, { mergeWithLastSubmission = true } = {}) {
261261
const returnTo = await this.interactionResult(req, res, result, { mergeWithLastSubmission });
262262

263-
res.statusCode = 302; // eslint-disable-line no-param-reassign
263+
res.statusCode = 303; // eslint-disable-line no-param-reassign
264264
res.setHeader('Location', returnTo);
265265
res.setHeader('Content-Length', '0');
266266
res.end();

lib/response_modes/fragment.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ const formatUri = require('../helpers/redirect_uri');
22

33
module.exports = (ctx, redirectUri, payload) => {
44
const uri = formatUri(redirectUri, payload, 'fragment');
5+
ctx.status = 303;
56
ctx.redirect(uri);
67
};

lib/response_modes/query.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ const formatUri = require('../helpers/redirect_uri');
22

33
module.exports = (ctx, redirectUri, payload) => {
44
const uri = formatUri(redirectUri, payload, 'query');
5+
ctx.status = 303;
56
ctx.redirect(uri);
67
};

test/auth_time/auth_time.test.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('responds with a id_token containing auth_time', () => {
2323
let id_token;
2424

2525
await this.wrap({ route: '/auth', verb: 'get', auth })
26-
.expect(302)
26+
.expect(303)
2727
.expect(auth.validateFragment)
2828
.expect(auth.validatePresence(['id_token', 'state']))
2929
.expect(auth.validateState)
@@ -54,7 +54,7 @@ describe('responds with a id_token containing auth_time', () => {
5454
let id_token;
5555

5656
await this.wrap({ route: '/auth', verb: 'get', auth })
57-
.expect(302)
57+
.expect(303)
5858
.expect(auth.validateFragment)
5959
.expect(auth.validatePresence(['id_token', 'state']))
6060
.expect(auth.validateState)
@@ -76,7 +76,7 @@ describe('responds with a id_token containing auth_time', () => {
7676
let id_token;
7777

7878
await this.wrap({ route: '/auth', verb: 'get', auth })
79-
.expect(302)
79+
.expect(303)
8080
.expect(auth.validateFragment)
8181
.expect(auth.validatePresence(['id_token', 'state']))
8282
.expect(auth.validateState)
@@ -99,7 +99,7 @@ describe('responds with a id_token containing auth_time', () => {
9999
let id_token;
100100

101101
await this.wrap({ route: '/auth', verb: 'get', auth })
102-
.expect(302)
102+
.expect(303)
103103
.expect(auth.validateFragment)
104104
.expect(auth.validatePresence(['id_token', 'state']))
105105
.expect(auth.validateState)
@@ -121,7 +121,7 @@ describe('responds with a id_token containing auth_time', () => {
121121
let id_token;
122122

123123
await this.wrap({ route: '/auth', verb: 'get', auth })
124-
.expect(302)
124+
.expect(303)
125125
.expect(auth.validateFragment)
126126
.expect(auth.validatePresence(['id_token', 'state']))
127127
.expect(auth.validateState)

test/authorization_code/code.grant.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('grant_type=authorization_code', () => {
3636
response_type: 'code',
3737
redirect_uri: 'https://client.example.com/cb',
3838
})
39-
.expect(302)
39+
.expect(303)
4040
.expect((response) => {
4141
const { query: { code } } = parseUrl(response.headers.location, true);
4242
const jti = this.getTokenJti(code);
@@ -310,7 +310,7 @@ describe('grant_type=authorization_code', () => {
310310
response_type: 'code',
311311
redirect_uri: 'https://client.example.com/cb3',
312312
})
313-
.expect(302)
313+
.expect(303)
314314
.expect((response) => {
315315
const { query: { code } } = parseUrl(response.headers.location, true);
316316
this.ac = code;
@@ -354,7 +354,7 @@ describe('grant_type=authorization_code', () => {
354354
scope: 'openid',
355355
response_type: 'code',
356356
})
357-
.expect(302)
357+
.expect(303)
358358
.expect((response) => {
359359
const { query: { code } } = parseUrl(response.headers.location, true);
360360
const jti = this.getTokenJti(code);

test/backchannel_logout/backchannel_logout.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ describe('Back-Channel Logout 1.0', () => {
9393
response_type: 'code id_token',
9494
redirect_uri: 'https://client.example.com/cb',
9595
})
96-
.expect(302)
96+
.expect(303)
9797
.expect((response) => {
9898
const { query } = parseUrl(response.headers.location.replace('#', '?'), true);
9999
expect(query).to.have.property('code');
@@ -176,7 +176,7 @@ describe('Back-Channel Logout 1.0', () => {
176176
return this.agent.post('/session/end/confirm')
177177
.send(params)
178178
.type('form')
179-
.expect(302)
179+
.expect(303)
180180
.expect(() => {
181181
(() => {
182182
const { sid } = session.authorizations.client;
@@ -211,7 +211,7 @@ describe('Back-Channel Logout 1.0', () => {
211211
return this.agent.post('/session/end/confirm')
212212
.send(params)
213213
.type('form')
214-
.expect(302)
214+
.expect(303)
215215
.expect(() => {
216216
expect(client.backchannelLogout.called).to.be.true;
217217
expect(client.backchannelLogout.calledWith(accountId, sid)).to.be.true;
@@ -234,7 +234,7 @@ describe('Back-Channel Logout 1.0', () => {
234234
return this.agent.post('/session/end/confirm')
235235
.send(params)
236236
.type('form')
237-
.expect(302)
237+
.expect(303)
238238
.expect(() => {
239239
expect(client.backchannelLogout.called).to.be.false;
240240
client.backchannelLogout.restore();

test/certificate_bound_access_tokens/certificate_bound_access_tokens.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ describe('features.mTLS.certificateBoundAccessTokens', () => {
257257
});
258258

259259
await this.wrap({ route: '/auth', verb: 'get', auth })
260-
.expect(302)
260+
.expect(303)
261261
.expect(auth.validateClientLocation)
262262
.expect(({ headers: { location } }) => {
263263
const { query: { code } } = url.parse(location, true);
@@ -376,7 +376,7 @@ describe('features.mTLS.certificateBoundAccessTokens', () => {
376376
});
377377

378378
await this.wrap({ route: '/auth', verb: 'get', auth })
379-
.expect(302)
379+
.expect(303)
380380
.expect(auth.validateClientLocation)
381381
.expect(({ headers: { location } }) => {
382382
const { query: { code } } = url.parse(location, true);

0 commit comments

Comments
 (0)