ep_openid_connect 3.0.24 → 3.0.25

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.
package/README.md CHANGED
@@ -49,6 +49,11 @@ Etherpad's `requireAuthentication` setting must be `true`.
49
49
  * `client_id` (required): The OAuth2 client ID issued by the identity provider.
50
50
  * `client_secret` (required): The OAuth2 client secret issued by the identity
51
51
  provider.
52
+ * `token_endpoint_auth_method` (optional; defaults to `client_secret_basic`):
53
+ Client authentication method to use for token endpoint requests. Supported
54
+ values are `client_secret_basic` and `client_secret_post`. Use
55
+ `client_secret_post` if your identity provider expects the client secret in
56
+ the token request body instead of the HTTP `Authorization` header.
52
57
  * `base_url` (required): The public base Etherpad URL. When registering Etherpad
53
58
  with your identity provider, the redirect URL (a.k.a. callback URL) is this
54
59
  base URL plus `/ep_openid_connect/callback`.
package/index.js CHANGED
@@ -10,6 +10,7 @@ for (const level of ['debug', 'info', 'warn', 'error']) {
10
10
  const defaultSettings = {
11
11
  prohibited_usernames: ['admin', 'guest'],
12
12
  scope: ['openid'],
13
+ token_endpoint_auth_method: 'client_secret_basic',
13
14
  user_properties: {},
14
15
  };
15
16
  let settings;
@@ -33,6 +34,7 @@ const validSettings = new Ajv().compile({
33
34
  issuer_metadata: {},
34
35
  prohibited_usernames: {elements: {type: 'string'}},
35
36
  scope: {elements: {type: 'string'}},
37
+ token_endpoint_auth_method: {enum: ['client_secret_basic', 'client_secret_post']},
36
38
  user_properties: {values: {
37
39
  optionalProperties: {
38
40
  claim: {type: 'string'},
@@ -100,11 +102,25 @@ const discoverConfig = async (issuerUrl, clientId, clientAuth) => {
100
102
  }
101
103
  };
102
104
 
105
+ const getClientAuth = (settings) => {
106
+ switch (settings.token_endpoint_auth_method) {
107
+ case 'client_secret_basic':
108
+ // eslint-disable-next-line new-cap
109
+ return oidc.ClientSecretBasic(settings.client_secret);
110
+ case 'client_secret_post':
111
+ // eslint-disable-next-line new-cap
112
+ return oidc.ClientSecretPost(settings.client_secret);
113
+ default:
114
+ throw new Error(
115
+ `Unsupported token endpoint auth method: ${settings.token_endpoint_auth_method}`);
116
+ }
117
+ };
118
+
103
119
  const buildConfig = async (settings) => {
104
120
  // openid-client@5 defaulted the token endpoint auth method to
105
121
  // `client_secret_basic`; v6 defaults to `client_secret_post`. Pin the
106
- // method explicitly so existing IdP registrations keep working.
107
- const clientAuth = oidc.ClientSecretBasic(settings.client_secret);
122
+ // default method explicitly so existing IdP registrations keep working.
123
+ const clientAuth = getClientAuth(settings);
108
124
  if (settings.issuer) {
109
125
  const config =
110
126
  await discoverConfig(settings.issuer, settings.client_id, clientAuth);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ep_openid_connect",
3
- "version": "3.0.24",
3
+ "version": "3.0.25",
4
4
  "description": "Etherpad plugin to authenticate users against an OpenID Connect provider.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -125,6 +125,31 @@ describe(__filename, function () {
125
125
  assert.equal(msg.data.readonly, false);
126
126
  });
127
127
 
128
+ describe('token_endpoint_auth_method', function () {
129
+ for (const tokenEndpointAuthMethod of ['client_secret_basic', 'client_secret_post']) {
130
+ it(`supports ${tokenEndpointAuthMethod}`, async function () {
131
+ await epOpenidConnect.loadSettings('loadSettings', {settings: {ep_openid_connect: {
132
+ ...pluginSettings,
133
+ token_endpoint_auth_method: tokenEndpointAuthMethod,
134
+ }}});
135
+ const padId = common.randomString();
136
+ const url = new URL(`/p/${padId}`, common.baseUrl).toString();
137
+ const res = await login(agent, issuer, url, 'normalUser');
138
+ assert.equal(res.request.url, url);
139
+ assert.equal(res.status, 200);
140
+ });
141
+ }
142
+
143
+ it('rejects unsupported methods', async function () {
144
+ await epOpenidConnect.loadSettings('loadSettings', {settings: {ep_openid_connect: {
145
+ ...pluginSettings,
146
+ token_endpoint_auth_method: 'unsupported',
147
+ }}});
148
+ await agent.get(new URL('/ep_openid_connect/login', common.baseUrl))
149
+ .expect(401);
150
+ });
151
+ });
152
+
128
153
  it('noCreate user is unable to create a pad', async function () {
129
154
  const padId = common.randomString();
130
155
  const url = new URL(`/p/${padId}`, common.baseUrl).toString();