@cloudflare/workers-oauth-provider 0.7.0 → 0.7.1

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.
@@ -809,6 +809,18 @@ interface ClientInfo {
809
809
  * URL to the client's JSON Web Key Set for validating signatures
810
810
  */
811
811
  jwksUri?: string;
812
+ /**
813
+ * RFC 7591 §2.2 internationalized variants of the human-readable client
814
+ * metadata fields, keyed by the raw member name including its BCP 47 language
815
+ * tag (e.g. `"client_name#ja"`, `"tos_uri#fr"`).
816
+ *
817
+ * Only the human-readable fields the RFC names are captured here:
818
+ * `client_name`, `client_uri`, `logo_uri`, `tos_uri`, and `policy_uri`.
819
+ * The canonical (un-tagged) values continue to live in their own typed
820
+ * fields above; this map holds only the locale-specific variants so that
821
+ * consumers can perform their own locale selection.
822
+ */
823
+ i18n?: Record<string, string>;
812
824
  /**
813
825
  * List of email addresses for contacting the client developers
814
826
  */
@@ -1921,12 +1921,13 @@ var OAuthProviderImpl = class OAuthProviderImpl {
1921
1921
  clientInfo = {
1922
1922
  clientId,
1923
1923
  redirectUris,
1924
- clientName: OAuthProviderImpl.validateStringField(clientMetadata.client_name),
1925
- logoUri: OAuthProviderImpl.validateStringField(clientMetadata.logo_uri),
1926
- clientUri: OAuthProviderImpl.validateStringField(clientMetadata.client_uri),
1927
- policyUri: OAuthProviderImpl.validateStringField(clientMetadata.policy_uri),
1928
- tosUri: OAuthProviderImpl.validateStringField(clientMetadata.tos_uri),
1929
- jwksUri: OAuthProviderImpl.validateStringField(clientMetadata.jwks_uri),
1924
+ clientName: OAuthProviderImpl.validateStringField(clientMetadata.client_name, "client_name"),
1925
+ logoUri: OAuthProviderImpl.validateOptionalUriField(clientMetadata.logo_uri, "logo_uri"),
1926
+ clientUri: OAuthProviderImpl.validateOptionalUriField(clientMetadata.client_uri, "client_uri"),
1927
+ policyUri: OAuthProviderImpl.validateOptionalUriField(clientMetadata.policy_uri, "policy_uri"),
1928
+ tosUri: OAuthProviderImpl.validateOptionalUriField(clientMetadata.tos_uri, "tos_uri"),
1929
+ jwksUri: OAuthProviderImpl.validateOptionalUriField(clientMetadata.jwks_uri, "jwks_uri"),
1930
+ i18n: OAuthProviderImpl.extractI18nFields(clientMetadata),
1930
1931
  contacts: OAuthProviderImpl.validateStringArray(clientMetadata.contacts),
1931
1932
  grantTypes: OAuthProviderImpl.validateStringArray(clientMetadata.grant_types) || [
1932
1933
  GrantType.AUTHORIZATION_CODE,
@@ -1960,6 +1961,9 @@ var OAuthProviderImpl = class OAuthProviderImpl {
1960
1961
  registration_client_uri: `${this.options.clientRegistrationEndpoint}/${clientId}`,
1961
1962
  client_id_issued_at: clientInfo.registrationDate
1962
1963
  };
1964
+ if (clientInfo.i18n) {
1965
+ for (const [key, value] of Object.entries(clientInfo.i18n)) if (!(key in response)) response[key] = value;
1966
+ }
1963
1967
  if (clientSecret) {
1964
1968
  response.client_secret = clientSecret;
1965
1969
  response.client_secret_expires_at = this.options.clientRegistrationTTL && clientInfo.registrationDate ? clientInfo.registrationDate + this.options.clientRegistrationTTL : 0;
@@ -2203,6 +2207,70 @@ var OAuthProviderImpl = class OAuthProviderImpl {
2203
2207
  return field;
2204
2208
  }
2205
2209
  /**
2210
+ * Validates that a field is an optional URI string using a safe scheme.
2211
+ *
2212
+ * Client metadata URI fields (e.g. logo_uri, client_uri, policy_uri, tos_uri,
2213
+ * jwks_uri) are frequently rendered into HTML attributes such as `<a href>` or
2214
+ * `<img src>` on consent screens. Permitting non-http(s) schemes such as
2215
+ * `javascript:` or `data:` would allow script execution in that context, so we
2216
+ * require an absolute http: or https: URL here, matching how redirect URIs are
2217
+ * already restricted.
2218
+ *
2219
+ * @param field - The field to validate
2220
+ * @param fieldName - Name of the field for error messages
2221
+ * @returns The validated URI string or undefined
2222
+ * @throws Error if the field is not a string or is not an absolute http(s) URL
2223
+ */
2224
+ static validateOptionalUriField(field, fieldName) {
2225
+ const value = OAuthProviderImpl.validateStringField(field, fieldName);
2226
+ if (value === void 0) return void 0;
2227
+ let parsed;
2228
+ try {
2229
+ parsed = new URL(value);
2230
+ } catch {
2231
+ throw new Error(`Invalid ${fieldName}: must be an absolute http: or https: URL`);
2232
+ }
2233
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error(`Invalid ${fieldName}: must be an absolute http: or https: URL`);
2234
+ return value;
2235
+ }
2236
+ static {
2237
+ this.I18N_FIELDS = {
2238
+ client_name: "string",
2239
+ client_uri: "uri",
2240
+ logo_uri: "uri",
2241
+ tos_uri: "uri",
2242
+ policy_uri: "uri"
2243
+ };
2244
+ }
2245
+ /**
2246
+ * Extracts RFC 7591 §2.2 internationalized metadata variants from a raw
2247
+ * registration payload.
2248
+ *
2249
+ * Localized variants are expressed by appending a `#<BCP 47 language tag>`
2250
+ * suffix to a metadata member name (e.g. `client_name#ja`, `tos_uri#fr`).
2251
+ * Only the human-readable fields the RFC names are considered; each value is
2252
+ * validated with the same rules as its canonical field (URI fields must be
2253
+ * absolute http(s) URLs). The raw `field#tag` keys are preserved verbatim so
2254
+ * that consumers can do their own locale matching.
2255
+ *
2256
+ * @param raw - The parsed client metadata object
2257
+ * @returns A map of `field#tag` to validated value, or undefined if none present
2258
+ * @throws Error if a localized value fails its field's validation
2259
+ */
2260
+ static extractI18nFields(raw) {
2261
+ const result = {};
2262
+ for (const key of Object.keys(raw)) {
2263
+ const hashIndex = key.indexOf("#");
2264
+ if (hashIndex <= 0 || hashIndex === key.length - 1) continue;
2265
+ const baseField = key.slice(0, hashIndex);
2266
+ const kind = OAuthProviderImpl.I18N_FIELDS[baseField];
2267
+ if (!kind) continue;
2268
+ const validated = kind === "uri" ? OAuthProviderImpl.validateOptionalUriField(raw[key], key) : OAuthProviderImpl.validateStringField(raw[key], key);
2269
+ if (validated !== void 0) result[key] = validated;
2270
+ }
2271
+ return Object.keys(result).length > 0 ? result : void 0;
2272
+ }
2273
+ /**
2206
2274
  * Validates that a field is a string array or undefined
2207
2275
  * @param arr - The array to validate
2208
2276
  * @param fieldName - Name of the field for error messages
@@ -2250,11 +2318,12 @@ var OAuthProviderImpl = class OAuthProviderImpl {
2250
2318
  clientId,
2251
2319
  redirectUris,
2252
2320
  clientName: OAuthProviderImpl.validateStringField(rawMetadata.client_name, "client_name"),
2253
- clientUri: OAuthProviderImpl.validateStringField(rawMetadata.client_uri, "client_uri"),
2254
- logoUri: OAuthProviderImpl.validateStringField(rawMetadata.logo_uri, "logo_uri"),
2255
- policyUri: OAuthProviderImpl.validateStringField(rawMetadata.policy_uri, "policy_uri"),
2256
- tosUri: OAuthProviderImpl.validateStringField(rawMetadata.tos_uri, "tos_uri"),
2257
- jwksUri: OAuthProviderImpl.validateStringField(rawMetadata.jwks_uri, "jwks_uri"),
2321
+ clientUri: OAuthProviderImpl.validateOptionalUriField(rawMetadata.client_uri, "client_uri"),
2322
+ logoUri: OAuthProviderImpl.validateOptionalUriField(rawMetadata.logo_uri, "logo_uri"),
2323
+ policyUri: OAuthProviderImpl.validateOptionalUriField(rawMetadata.policy_uri, "policy_uri"),
2324
+ tosUri: OAuthProviderImpl.validateOptionalUriField(rawMetadata.tos_uri, "tos_uri"),
2325
+ jwksUri: OAuthProviderImpl.validateOptionalUriField(rawMetadata.jwks_uri, "jwks_uri"),
2326
+ i18n: OAuthProviderImpl.extractI18nFields(rawMetadata),
2258
2327
  contacts: OAuthProviderImpl.validateStringArray(rawMetadata.contacts, "contacts"),
2259
2328
  grantTypes: OAuthProviderImpl.validateStringArray(rawMetadata.grant_types, "grant_types") || ["authorization_code"],
2260
2329
  responseTypes: OAuthProviderImpl.validateStringArray(rawMetadata.response_types, "response_types") || ["code"],
@@ -2942,6 +3011,7 @@ var OAuthHelpersImpl = class {
2942
3011
  policyUri: clientInfo.policyUri,
2943
3012
  tosUri: clientInfo.tosUri,
2944
3013
  jwksUri: clientInfo.jwksUri,
3014
+ i18n: clientInfo.i18n,
2945
3015
  contacts: clientInfo.contacts,
2946
3016
  grantTypes: clientInfo.grantTypes || [
2947
3017
  GrantType.AUTHORIZATION_CODE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/workers-oauth-provider",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "OAuth provider for Cloudflare Workers",
5
5
  "main": "dist/oauth-provider.js",
6
6
  "types": "dist/oauth-provider.d.ts",