forked from panva/node-oidc-provider
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoidc_context.js
107 lines (83 loc) · 3.37 KB
/
oidc_context.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'use strict';
const _ = require('lodash');
const url = require('url');
const uuid = require('uuid');
const debug = require('debug')('oidc-provider:bearer');
const errors = require('./errors');
const providerInstance = require('../helpers/weak_cache');
module.exports = function getContext(provider) {
const map = new WeakMap();
const acrValues = providerInstance(provider).configuration('acrValues');
function instance(ctx) {
if (!map.has(ctx)) map.set(ctx, { claims: {} });
return map.get(ctx);
}
class OIDCContext {
constructor(ctx) {
Object.defineProperty(this, 'ctx', { value: ctx });
Object.defineProperty(this, 'authorization', { writable: true });
Object.defineProperty(this, 'redirectUriCheckPerformed', { writable: true });
Object.defineProperty(this, 'nativeAuthSkip', { writable: true });
this.uuid = uuid();
}
urlFor(name, opt) {
const mountPath = (this.ctx.req.originalUrl && this.ctx.req.originalUrl.substring(0,
this.ctx.req.originalUrl.indexOf(this.ctx.request.url))) ||
this.ctx.mountPath || // koa-mount
this.ctx.req.baseUrl || // expressApp.use('/op', provider.callback);
''; // no mount
return url.resolve(this.ctx.href, provider.pathFor(name, Object.assign({ mountPath }, opt)));
}
prompted(name) {
if (!this.result) {
return this.prompts && this.prompts.indexOf(name) !== -1;
}
if (name === 'none') return true;
const should = _.difference(this.prompts, _.keys(this.result));
return should.indexOf(name) !== -1;
}
get acr() {
return _.get(this, 'result.login.acr', acrValues[0]);
}
get amr() {
return _.get(this, 'result.login.amr', undefined);
}
set body(value) { Object.defineProperty(this, 'body', { enumerable: true, value }); }
set params(value) { Object.defineProperty(this, 'params', { enumerable: true, value }); }
set account(value) { Object.defineProperty(this, 'account', { value }); }
set client(value) { Object.defineProperty(this, 'client', { value }); }
set claims(value) { instance(this).claims = value; }
get prompts() { return this.params.prompt ? this.params.prompt.split(' ') : []; }
get claims() { return instance(this).claims; }
get bearer() {
const ctx = this.ctx;
const mechanisms = _.omitBy({
body: _.get(ctx.oidc, 'body.access_token'),
header: ctx.headers.authorization,
query: ctx.query.access_token,
}, _.isUndefined);
debug('uuid=%s received bearer via %o', this.uuid, mechanisms);
const length = Object.keys(mechanisms).length;
if (!length) throw new errors.InvalidRequestError('no bearer token provided');
if (length > 1) {
throw new errors.InvalidRequestError(
'bearer token must only be provided using one mechanism');
}
let bearer;
_.forEach(mechanisms, (value, mechanism) => {
if (mechanism === 'header') {
const parts = value.split(' ');
if (parts.length !== 2 || parts[0] !== 'Bearer') {
throw new errors.InvalidRequestError('invalid authorization header value format');
}
bearer = parts[1];
} else {
bearer = value;
}
});
if (!bearer) throw new errors.InvalidRequestError('no bearer token provided');
return bearer;
}
}
return OIDCContext;
};