ep_openid_connect 2.0.7 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,3 @@
1
- # You need to change lines 38 and 46 in case the plugin's name on npmjs.com is different
2
- # from the repository name
3
-
4
1
  name: "Backend tests"
5
2
 
6
3
  # any branch is useful for testing before a PR is submitted
@@ -17,6 +14,10 @@ jobs:
17
14
  runs-on: ubuntu-latest
18
15
 
19
16
  steps:
17
+ - uses: actions/setup-node@v2
18
+ with:
19
+ node-version: 12
20
+
20
21
  - name: Install libreoffice
21
22
  run: |
22
23
  sudo add-apt-repository -y ppa:libreoffice/ppa
@@ -32,19 +33,29 @@ jobs:
32
33
  - name: Install all dependencies and symlink for ep_etherpad-lite
33
34
  run: src/bin/installDeps.sh
34
35
 
35
- # clone this repository into node_modules/ep_plugin-name
36
36
  - name: Checkout plugin repository
37
37
  uses: actions/checkout@v2
38
38
  with:
39
- path: ./node_modules/${{github.event.repository.name}}
39
+ path: ./node_modules/__tmp
40
+
41
+ - name: Determine plugin name
42
+ id: plugin_name
43
+ run: |
44
+ cd ./node_modules/__tmp
45
+ npx -c 'printf %s\\n "::set-output name=plugin_name::${npm_package_name}"'
46
+
47
+ - name: Rename plugin directory
48
+ run: |
49
+ mv ./node_modules/__tmp ./node_modules/"${PLUGIN_NAME}"
50
+ env:
51
+ PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
40
52
 
41
53
  - name: Install plugin dependencies
42
54
  run: |
43
- cd node_modules/${{github.event.repository.name}}
55
+ cd ./node_modules/"${PLUGIN_NAME}"
44
56
  npm ci
57
+ env:
58
+ PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
45
59
 
46
60
  - name: Run the backend tests
47
61
  run: cd src && npm test
48
-
49
- ##ETHERPAD_NPM_V=2
50
- ## NPM configuration automatically created using src/bin/plugins/updateAllPluginsScript.sh
@@ -0,0 +1,92 @@
1
+ # Publicly credit Sauce Labs because they generously support open source
2
+ # projects.
3
+ name: "frontend tests powered by Sauce Labs"
4
+
5
+ on: [push]
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - name: Generate Sauce Labs strings
13
+ id: sauce_strings
14
+ run: |
15
+ printf %s\\n '::set-output name=name::${{github.event.repository.name}} ${{ github.workflow }} - ${{ github.job }}'
16
+ printf %s\\n '::set-output name=tunnel_id::${{ github.run_id }}-${{ github.run_number }}-${{ github.job }}'
17
+
18
+ - uses: actions/setup-node@v2
19
+ with:
20
+ node-version: 12
21
+
22
+ - name: Check out Etherpad core
23
+ uses: actions/checkout@v2
24
+ with:
25
+ repository: ether/etherpad-lite
26
+
27
+ - name: Check out the plugin
28
+ uses: actions/checkout@v2
29
+ with:
30
+ path: ./node_modules/__tmp
31
+
32
+ - name: export GIT_HASH to env
33
+ id: environment
34
+ run: |
35
+ cd ./node_modules/__tmp
36
+ echo "::set-output name=sha_short::$(git rev-parse --short ${{ github.sha }})"
37
+
38
+ - name: Determine plugin name
39
+ id: plugin_name
40
+ run: |
41
+ cd ./node_modules/__tmp
42
+ npx -c 'printf %s\\n "::set-output name=plugin_name::${npm_package_name}"'
43
+
44
+ - name: Rename plugin directory
45
+ env:
46
+ PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
47
+ run: |
48
+ mv ./node_modules/__tmp ./node_modules/"${PLUGIN_NAME}"
49
+
50
+ - name: Install plugin dependencies
51
+ env:
52
+ PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
53
+ run: |
54
+ cd ./node_modules/"${PLUGIN_NAME}"
55
+ npm ci
56
+
57
+ # This must be run after setting up the plugin, otherwise npm will try to
58
+ # hoist common dependencies by removing them from src/node_modules and
59
+ # installing them in the top-level node_modules. As of v6.14.10, npm's hoist
60
+ # logic appears to be buggy, because it sometimes removes dependencies from
61
+ # src/node_modules but fails to add them to the top-level node_modules. Even
62
+ # if npm correctly hoists the dependencies, the hoisting seems to confuse
63
+ # tools such as `npm outdated`, `npm update`, and some ESLint rules.
64
+ - name: Install Etherpad core dependencies
65
+ run: src/bin/installDeps.sh
66
+
67
+ - name: Create settings.json
68
+ run: cp settings.json.template settings.json
69
+
70
+ - name: Disable import/export rate limiting
71
+ run: |
72
+ sed -e '/^ *"importExportRateLimiting":/,/^ *\}/ s/"max":.*/"max": 0/' -i settings.json
73
+
74
+ - name: Remove standard frontend test files
75
+ run: rm -rf src/tests/frontend/specs
76
+
77
+ - uses: saucelabs/sauce-connect-action@v1
78
+ with:
79
+ username: ${{ secrets.SAUCE_USERNAME }}
80
+ accessKey: ${{ secrets.SAUCE_ACCESS_KEY }}
81
+ tunnelIdentifier: ${{ steps.sauce_strings.outputs.tunnel_id }}
82
+
83
+ - name: Run the frontend tests
84
+ shell: bash
85
+ env:
86
+ SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}
87
+ SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
88
+ SAUCE_NAME: ${{ steps.sauce_strings.outputs.name }}
89
+ TRAVIS_JOB_NUMBER: ${{ steps.sauce_strings.outputs.tunnel_id }}
90
+ GIT_HASH: ${{ steps.environment.outputs.sha_short }}
91
+ run: |
92
+ src/tests/frontend/travis/runner.sh
@@ -56,15 +56,22 @@ jobs:
56
56
  runs-on: ubuntu-latest
57
57
  steps:
58
58
  - uses: actions/checkout@v2
59
+ with:
60
+ fetch-depth: 0
59
61
  - uses: actions/setup-node@v1
60
62
  with:
61
63
  node-version: 12
62
64
  registry-url: https://registry.npmjs.org/
63
- - run: git config user.name 'github-actions[bot]'
64
- - run: git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
65
- - run: npm ci
66
- - run: npm version patch
67
- - run: git push --follow-tags
65
+ - name: Bump version (patch)
66
+ run: |
67
+ LATEST_TAG=$(git describe --tags --abbrev=0) || exit 1
68
+ NEW_COMMITS=$(git rev-list --count "${LATEST_TAG}"..) || exit 1
69
+ [ "${NEW_COMMITS}" -gt 0 ] || exit 0
70
+ git config user.name 'github-actions[bot]'
71
+ git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
72
+ npm ci
73
+ npm version patch
74
+ git push --follow-tags
68
75
  # `npm publish` must come after `git push` otherwise there is a race
69
76
  # condition: If two PRs are merged back-to-back then master/main will be
70
77
  # updated with the commits from the second PR before the first PR's
@@ -78,6 +85,3 @@ jobs:
78
85
  - run: npm publish
79
86
  env:
80
87
  NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
81
-
82
- ##ETHERPAD_NPM_V=2
83
- ## NPM configuration automatically created using bin/plugins/updateAllPluginsScript.sh
package/README.md CHANGED
@@ -34,18 +34,30 @@ Etherpad's `requireAuthentication` setting must be `true`.
34
34
 
35
35
  ### Configuration Details
36
36
 
37
- * `issuer` (required): The base URL of the OpenID Connect identity provider,
38
- used to perform discovery of the endpoints.
37
+ * `issuer` (required if `issuer_metadata` is not set): The base URL of the
38
+ OpenID Connect identity provider, used to discover the relevant OpenID Connect
39
+ endpoints. If set, your identity provider must support the [OpenID Connect
40
+ Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html)
41
+ protocol.
42
+ * `issuer_metadata` (required if `issuer` is not set): Object containing details
43
+ about your OpenID Connect identity provider. Used for manual configuration if
44
+ your identity provider does not support the Discovery protocol. If your
45
+ identity provider does support Discovery, you are encouraged to set `issuer`
46
+ instead. For properties, see the [documentation for the openid-client `Issuer`
47
+ object
48
+ constructor](https://github.com/panva/node-openid-client/blob/v4.7.4/docs/README.md#new-issuermetadata).
39
49
  * `client_id` (required): The OAuth2 client ID issued by the identity provider.
40
50
  * `client_secret` (required): The OAuth2 client secret issued by the identity
41
51
  provider.
42
52
  * `base_url` (required): The public base Etherpad URL. When registering Etherpad
43
53
  with your identity provider, the redirect URL (a.k.a. callback URL) is this
44
54
  base URL plus `/ep_openid_connect/callback`.
45
- * `displayname_claim` (optional; defaults to `"name"`): The claim containing the
46
- name to display in the pad's user list.
55
+ * `displayname_claim` (optional; defaults to `"name"`): The default value of
56
+ `user_properties.displayname.claim`. **Deprecated:** Set
57
+ `user_properties.displayname.claim` instead.
47
58
  * `response_types` (optional; defaults to `["code"]`): List of OpenID Connect
48
59
  response types.
60
+ * `scope` (optional; defaults to `["openid"]`): List of OAuth2 scope strings.
49
61
  * `permit_displayname_change` (optional; defaults to `false`): Whether users may
50
62
  change their displayed name.
51
63
  * `prohibited_usernames` (optional; defaults to `['admin', 'guest']`): List of
@@ -54,6 +66,9 @@ Etherpad's `requireAuthentication` setting must be `true`.
54
66
  the users in the `users` setting and to avoid conflicts with other plugins
55
67
  (such as
56
68
  [ep\_readonly\_guest](https://github.com/ether/ep_readonly_guest#readme)).
69
+ * `user_properties` (optional): Object that controls the automatic creation of
70
+ additional properties on each authenticated user's account object. See below
71
+ for details.
57
72
 
58
73
  ## Interaction with the `users` Setting
59
74
 
@@ -63,15 +78,18 @@ identifier for the user.) Many identity providers (such as GitLab) identify
63
78
  users by a numeric user ID, so the `sub` claim (and thus the Etherpad username)
64
79
  will probably look something like "5374".
65
80
 
66
- All values associated with that username in the `settings.json` `users` object
67
- are applied to the user, including `is_admin`, `readOnly`, and `canCreate`.
68
-
69
- For example, if you want the user identified by "5374" to be a read-only user,
70
- you would add the following to your `settings.json`:
81
+ Each authenticated user gets their own account object. Default properties for a
82
+ user's account object come from the `users` setting in `settings.json`. Etherpad
83
+ uses the `is_admin`, `readOnly`, and `canCreate` properties to control access,
84
+ and this plugin uses the `displayname` property for the name displayed in the
85
+ user list. For example, the following sets the default display name to
86
+ "Firstname Lastname" and the default access to read-only for the user identified
87
+ by "5374":
71
88
 
72
89
  ```json
73
90
  "users": {
74
91
  "5374": {
92
+ "displayname": "Firstname Lastname",
75
93
  "readOnly": true
76
94
  }
77
95
  },
@@ -82,6 +100,54 @@ you can use the `prohibited_usernames` settings to force an authentication error
82
100
  if the `sub` claim happens to match. This is useful for preventing a malicious
83
101
  identity provider from gaining admin access to your Etherpad instance.
84
102
 
103
+ The `user_properties` setting can be used to automatically add or change
104
+ properties on a user's account object when the user authenticates. The
105
+ `user_properties` setting maps a property name to an object that describes how
106
+ the property's value is obtained. For example:
107
+
108
+ ```json
109
+ "ep_openid_connect": {
110
+ "user_properties": {
111
+ "fromClaimWithDefault": {
112
+ "claim": "claimName",
113
+ "default": "default value"
114
+ },
115
+ "fromClaimOrUnset": {
116
+ "claim": "claimName"
117
+ },
118
+ "fixedValue": {
119
+ "default": "fixed value"
120
+ }
121
+ }
122
+ },
123
+ ```
124
+
125
+ The above example sets properties as follows:
126
+ * Each user's `fromClaimWithDefault` property is set to the value of the user's
127
+ `claimName` claim if present, otherwise the property is left unchanged if
128
+ already set, otherwise it is set to the string `"default value"`.
129
+ * Each user's `fromClaimOrUnset` property is set to the value of the user's
130
+ `claimName` claim if present, otherwise the property is left unset/unchanged.
131
+ * Each user's `fixedValue` property is set to the string `"fixed value"`
132
+ unless already set.
133
+
134
+ You can use this feature to control access in the OpenID Connect provider if it
135
+ provides suitable claims:
136
+
137
+ ```json
138
+ "ep_openid_connect": {
139
+ "scope": ["openid", "etherpad"],
140
+ "user_properties": {
141
+ "is_admin": {"claim": "etherpad_is_admin"},
142
+ "readOnly": {"claim": "etherpad_readOnly"},
143
+ "canCreate": {"claim": "etherpad_canCreate"}
144
+ }
145
+ },
146
+ ```
147
+
148
+ To avoid breaking assumptions made by Etherpad, the `username` property cannot
149
+ be altered via the `user_properties` setting.
150
+
85
151
  ## Interaction with the ep\_readonly\_guest Plugin
86
152
 
87
153
  The [ep\_readonly\_guest
package/index.js CHANGED
@@ -5,78 +5,147 @@ const {URL} = require('url');
5
5
  const {Issuer, generators} = require('openid-client');
6
6
  const authorManager = require('ep_etherpad-lite/node/db/AuthorManager');
7
7
 
8
- const pluginName = 'ep_openid_connect';
9
- const logger = log4js.getLogger(pluginName);
8
+ const logger = log4js.getLogger('ep_openid_connect');
10
9
  const settings = {
11
10
  displayname_claim: 'name',
12
11
  response_types: ['code'],
13
12
  permit_displayname_change: false,
14
13
  prohibited_usernames: ['admin', 'guest'],
14
+ scope: ['openid'],
15
+ user_properties: {},
15
16
  };
16
17
  let oidcClient = null;
17
18
 
18
- const ep = (endpoint) => `/${pluginName}/${endpoint}`;
19
+ const ep = (endpoint) => `/ep_openid_connect/${endpoint}`;
19
20
  const endpointUrl = (endpoint) => new URL(ep(endpoint).substr(1), settings.base_url).toString();
20
21
 
21
- exports.loadSettings = async (hookName, {settings: {[pluginName]: config = {}}}) => {
22
+ const validateSubClaim = (sub) => {
23
+ if (typeof sub !== 'string' || // 'sub' claim must exist as a string per OIDC spec.
24
+ sub === '' || // Empty string doesn't make sense.
25
+ sub === '__proto__' || // Prevent prototype pollution.
26
+ settings.prohibited_usernames.includes(sub)) {
27
+ throw new Error('invalid sub claim');
28
+ }
29
+ };
30
+
31
+ const discoverIssuer = async (issuerUrl) => {
32
+ issuerUrl = new URL(issuerUrl);
33
+ // https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery says that the URI
34
+ // must not have query or fragment components.
35
+ if (issuerUrl.search) {
36
+ throw new Error(`Unexpected query in issuer URL (${issuerUrl}): ${issuerUrl.search}`);
37
+ }
38
+ if (issuerUrl.hash) {
39
+ throw new Error(`Unexpected fragment in issuer URL (${issuerUrl}): ${issuerUrl.hash}`);
40
+ }
41
+ let issuer;
42
+ try {
43
+ issuer = await Issuer.discover(issuerUrl.href);
44
+ } catch (err) {
45
+ // The URL used to get the issuer metadata doesn't exactly follow RFC 8615; see:
46
+ // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
47
+ const discoveryUrl = new URL(issuerUrl);
48
+ if (!discoveryUrl.pathname.includes('/.well-known/')) {
49
+ discoveryUrl.pathname =
50
+ `${discoveryUrl.pathname.replace(/\/$/, '')}/.well-known/openid-configuration`;
51
+ }
52
+ logger.error(
53
+ 'Failed to discover issuer metadata via OpenID Connect Discovery ' +
54
+ '(https://openid.net/specs/openid-connect-discovery-1_0.html). ' +
55
+ `Does your issuer support Discovery? (hint: ${discoveryUrl})`);
56
+ throw err;
57
+ }
58
+ logger.info('OpenID Connect Discovery complete.');
59
+ return issuer;
60
+ };
61
+
62
+ const getIssuer = async (settings) => {
63
+ if (settings.issuer) return await discoverIssuer(settings.issuer);
64
+ return new Issuer(settings.issuer_metadata);
65
+ };
66
+
67
+ exports.loadSettings = async (hookName, {settings: {ep_openid_connect: config = {}}}) => {
22
68
  Object.assign(settings, config);
23
- for (const setting of ['base_url', 'client_id', 'client_secret', 'issuer']) {
69
+ for (const setting of ['base_url', 'client_id', 'client_secret']) {
24
70
  if (!settings[setting]) {
25
- logger.error(`Required setting missing from settings.json: ${pluginName}.${setting}`);
71
+ logger.error(`Required setting missing from settings.json: ep_openid_connect.${setting}`);
26
72
  return;
27
73
  }
28
74
  }
75
+ if (!settings.issuer && !settings.issuer_metadata) {
76
+ logger.error(
77
+ 'Either ep_openid_connect.issuer or ep_openid_connect.issuer_metadata must be set');
78
+ return;
79
+ }
80
+ if (settings.issuer && settings.issuer_metadata) {
81
+ logger.warn('Ignoring ep_openid_connect.issuer_metadata setting ' +
82
+ 'because ep_openid_connect.issuer is set');
83
+ }
29
84
  // Make sure base_url ends with '/' so that relative URLs are appended:
30
85
  if (!settings.base_url.endsWith('/')) settings.base_url += '/';
31
- oidcClient = new (await Issuer.discover(settings.issuer)).Client({
86
+ settings.user_properties = {
87
+ displayname: {claim: settings.displayname_claim},
88
+ ...settings.user_properties,
89
+ // The username property must always match the key used in settings.users.
90
+ username: {claim: 'sub'},
91
+ };
92
+ oidcClient = new (await getIssuer(settings)).Client({
32
93
  client_id: settings.client_id,
33
94
  client_secret: settings.client_secret,
34
95
  response_types: settings.response_types,
35
96
  redirect_uris: [endpointUrl('callback')],
36
97
  });
37
- logger.info('Client discovery complete. Configured.');
98
+ logger.info('Configured.');
38
99
  };
39
100
 
40
101
  exports.clientVars = (hookName, context) => {
41
102
  if (oidcClient == null) return;
42
103
  const {permit_displayname_change} = settings;
43
- return {[pluginName]: {permit_displayname_change}};
104
+ return {ep_openid_connect: {permit_displayname_change}};
44
105
  };
45
106
 
46
107
  exports.expressCreateServer = (hookName, {app}) => {
47
108
  if (oidcClient == null) return;
48
109
  logger.debug('Configuring auth routes');
49
- app.get(ep('callback'), (req, res, next) => {
50
- logger.debug(`Processing ${req.url}`);
51
- (async () => {
110
+ app.get(ep('callback'), async (req, res, next) => {
111
+ // This handler MUST NOT redirect to a page that requires authentication if there is a problem,
112
+ // otherwise the user could be caught in an infinite redirect loop.
113
+ try {
114
+ logger.debug(`Processing ${req.url}`);
52
115
  const params = oidcClient.callbackParams(req);
53
- const oidcSession = req.session[pluginName] || {};
54
- const {authParams} = oidcSession;
55
- if (authParams == null) throw new Error('no authentication paramters found in session state');
56
- const tokenset = await oidcClient.callback(endpointUrl('callback'), params, authParams);
116
+ const oidcSession = req.session.ep_openid_connect || {};
117
+ if (oidcSession.authParams == null) throw new Error('missing authentication paramters');
118
+ const tokenset =
119
+ await oidcClient.callback(endpointUrl('callback'), params, oidcSession.authParams);
57
120
  const userinfo = await oidcClient.userinfo(tokenset);
58
- if (settings.prohibited_usernames.indexOf(userinfo.sub) !== -1) {
59
- throw new Error(`authenticated user's 'sub' claim (${userinfo.sub}) is not permitted`);
60
- }
61
- oidcSession.userinfo = userinfo;
121
+ validateSubClaim(userinfo.sub);
62
122
  // The user has successfully authenticated, but don't set req.session.user here -- do it in
63
123
  // the authenticate hook so that Etherpad can log the authentication success. However, DO "log
64
124
  // out" the previous user to force the authenticate hook to run in case the user was already
65
125
  // authenticated as someone else.
66
126
  delete req.session.user;
127
+ // userinfo should not be stored in req.session until after all checks have passed. (Otherwise
128
+ // it would be too easy to accidentally introduce a vulnerability.)
129
+ oidcSession.userinfo = userinfo;
67
130
  res.redirect(oidcSession.next || settings.base_url);
68
131
  // Defer deletion of state until success so that the user can reload the page to retry after a
69
132
  // transient backchannel failure.
70
133
  delete oidcSession.authParams;
71
134
  delete oidcSession.next;
72
- })().catch(next);
135
+ } catch (err) {
136
+ return next(err);
137
+ }
73
138
  });
74
139
  app.get(ep('login'), (req, res, next) => {
75
140
  logger.debug(`Processing ${req.url}`);
76
- if (req.session[pluginName] == null) req.session[pluginName] = {};
77
- const oidcSession = req.session[pluginName];
141
+ if (req.session.ep_openid_connect == null) req.session.ep_openid_connect = {};
142
+ const oidcSession = req.session.ep_openid_connect;
78
143
  oidcSession.next = req.query.redirect_uri || settings.base_url;
79
- oidcSession.authParams = {nonce: generators.nonce(), state: generators.state()};
144
+ oidcSession.authParams = {
145
+ nonce: generators.nonce(),
146
+ scope: settings.scope.join(' '),
147
+ state: generators.state(),
148
+ };
80
149
  res.redirect(oidcClient.authorizationUrl(oidcSession.authParams));
81
150
  });
82
151
  app.get(ep('logout'), (req, res) => req.session.destroy(() => res.redirect(settings.base_url)));
@@ -85,21 +154,26 @@ exports.expressCreateServer = (hookName, {app}) => {
85
154
  exports.authenticate = (hookName, {req, res, users}) => {
86
155
  if (oidcClient == null) return;
87
156
  logger.debug('authenticate hook for', req.url);
88
- const {session} = req;
89
- const {[pluginName]: {userinfo = {}} = {}} = session;
90
- const {sub} = userinfo;
91
- if (sub == null) {
157
+ const {ep_openid_connect: {userinfo} = {}} = req.session;
158
+ if (userinfo == null) { // Nullish means the user isn't authenticated.
92
159
  // Out of an abundance of caution, clear out the old state, nonce, and userinfo (if present) to
93
160
  // force regeneration.
94
- delete session[pluginName];
161
+ delete req.session.ep_openid_connect;
95
162
  // Authn failed. Let another plugin try to authenticate the user.
96
163
  return;
97
164
  }
98
165
  // Successfully authenticated.
99
- if (users[sub] == null) users[sub] = {};
100
- session.user = users[sub];
101
- session.user.username = sub;
102
- session.user.displayname = userinfo[settings.displayname_claim] || session.user.displayname;
166
+ logger.info('Successfully authenticated user with userinfo:', userinfo);
167
+ req.session.user = users[userinfo.sub];
168
+ if (req.session.user == null) req.session.user = users[userinfo.sub] = {};
169
+ for (const [propName, descriptor] of Object.entries(settings.user_properties)) {
170
+ if (descriptor.claim != null && descriptor.claim in userinfo) {
171
+ req.session.user[propName] = userinfo[descriptor.claim];
172
+ } else if ('default' in descriptor && !(propName in req.session.user)) {
173
+ req.session.user[propName] = descriptor.default;
174
+ }
175
+ }
176
+ logger.debug('User properties:', req.session.user);
103
177
  return true;
104
178
  };
105
179
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ep_openid_connect",
3
- "version": "2.0.7",
3
+ "version": "2.1.2",
4
4
  "description": "Etherpad plugin to authenticate users against an OpenID Connect provider.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -23,18 +23,18 @@
23
23
  },
24
24
  "homepage": "https://github.com/ether/ep_openid_connect#readme",
25
25
  "dependencies": {
26
- "openid-client": "^4.5.0"
26
+ "openid-client": "^4.7.4"
27
27
  },
28
28
  "devDependencies": {
29
- "eslint": "^7.22.0",
30
- "eslint-config-etherpad": "^1.0.26",
31
- "eslint-plugin-cypress": "^2.11.2",
29
+ "eslint": "^7.32.0",
30
+ "eslint-config-etherpad": "^2.0.2",
31
+ "eslint-plugin-cypress": "^2.12.1",
32
32
  "eslint-plugin-eslint-comments": "^3.2.0",
33
- "eslint-plugin-mocha": "^8.1.0",
33
+ "eslint-plugin-mocha": "^9.0.0",
34
34
  "eslint-plugin-node": "^11.1.0",
35
35
  "eslint-plugin-prefer-arrow": "^1.2.3",
36
- "eslint-plugin-promise": "^4.3.1",
37
- "eslint-plugin-you-dont-need-lodash-underscore": "^6.11.0"
36
+ "eslint-plugin-promise": "^5.1.1",
37
+ "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0"
38
38
  },
39
39
  "eslintConfig": {
40
40
  "root": true,
@@ -46,12 +46,12 @@
46
46
  },
47
47
  "funding": {
48
48
  "type": "individual",
49
- "url": "http://etherpad.org/"
49
+ "url": "https://etherpad.org/"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "ep_etherpad-lite": ">=1.8.6"
53
53
  },
54
54
  "engines": {
55
- "node": ">=10.13.0"
55
+ "node": ">=12.13.0"
56
56
  }
57
57
  }