Skip to content

Commit 09a6ef4

Browse files
apognuChibiBlasphem
authored andcommitted
Use child class for tokens to override parsing implementations.
1 parent 38a5e18 commit 09a6ef4

File tree

3 files changed

+38
-20
lines changed

3 files changed

+38
-20
lines changed

bun.lock

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"@tanstack/react-query-devtools": "5.83.1",
6161
"@tanstack/react-table": "^8.21.2",
6262
"@tanstack/react-virtual": "3.13.12",
63+
"arctic": "^3.7.0",
6364
"autosuggest-highlight": "^3.3.4",
6465
"class-variance-authority": "^0.7.1",
6566
"clsx": "^2.1.1",
@@ -94,7 +95,6 @@
9495
"reactflow": "^11.11.4",
9596
"remeda": "^2.21.2",
9697
"remix-auth-oauth2": "^3.4.1",
97-
"remix-auth-openid": "^0.3.0",
9898
"remix-i18next": "^6.4.1",
9999
"remix-utils": "^7.7.0",
100100
"sharpstate": "^0.0.13",
@@ -2192,8 +2192,6 @@
21922192

21932193
"jiti": ["[email protected]", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="],
21942194

2195-
"jose": ["[email protected]", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="],
2196-
21972195
"js-beautify": ["[email protected]", "", { "dependencies": { "config-chain": "^1.1.13", "editorconfig": "^1.0.4", "glob": "^10.4.2", "js-cookie": "^3.0.5", "nopt": "^7.2.1" }, "bin": { "css-beautify": "js/bin/css-beautify.js", "html-beautify": "js/bin/html-beautify.js", "js-beautify": "js/bin/js-beautify.js" } }, "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA=="],
21982196

21992197
"js-cookie": ["[email protected]", "", {}, "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="],
@@ -2534,14 +2532,12 @@
25342532

25352533
"object-assign": ["[email protected]", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
25362534

2537-
"object-hash": ["object-hash@2.2.0", "", {}, "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw=="],
2535+
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
25382536

25392537
"object-inspect": ["[email protected]", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
25402538

25412539
"object-to-formdata": ["[email protected]", "", {}, "sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw=="],
25422540

2543-
"oidc-token-hash": ["[email protected]", "", {}, "sha512-D7EmwxJV6DsEB6vOFLrBM2OzsVgQzgPWyHlV2OOAVj772n+WTXpudC9e9u5BVKQnYwaD30Ivhi9b+4UeBcGu9g=="],
2544-
25452541
"on-finished": ["[email protected]", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
25462542

25472543
"on-headers": ["[email protected]", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="],
@@ -2556,8 +2552,6 @@
25562552

25572553
"openapi-types": ["[email protected]", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
25582554

2559-
"openid-client": ["[email protected]", "", { "dependencies": { "jose": "^4.15.9", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" } }, "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew=="],
2560-
25612555
"opentelemetry-instrumentation-remix": ["[email protected]", "", { "dependencies": { "@opentelemetry/instrumentation": "^0.52.1", "@opentelemetry/semantic-conventions": "^1.25.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-2XhIEWfzHeQmxnzv9HzklwkgYMx4NuWwloZuVIwjUb9R28gH5j3rJPqjErTvYSyz0fLbw0gyI+gfYHKHn/v/1Q=="],
25622556

25632557
"ora": ["[email protected]", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="],
@@ -2834,8 +2828,6 @@
28342828

28352829
"remix-auth-oauth2": ["[email protected]", "", { "dependencies": { "@edgefirst-dev/data": "^0.0.4", "@mjackson/headers": "^0.10.0", "arctic": "^3.0.0" }, "peerDependencies": { "remix-auth": "^4.0.0" } }, "sha512-ZhGon1czdIsOw1/O9EcTCzapZB6FpT3u9vtXSVeEMwGNs+iWljRsibnUC1RtwJbzzCdLBSwIXTNTbiRmLZ4cZw=="],
28362830

2837-
"remix-auth-openid": ["[email protected]", "", { "dependencies": { "@mjackson/headers": "^0.9.0", "openid-client": "^5.0.0", "react-router": "^7.0.0" }, "peerDependencies": { "remix-auth": "^4.0.0" } }, "sha512-DUe7B+ITkHj6xYeCwmMtRpooLk6jJm3alSs2SDoolgvhiQXrekmvS67SlzdKI2yU+P3rPP+UTflQp7zn4UgIhg=="],
2838-
28392831
"remix-development-tools": ["[email protected]", "", { "dependencies": { "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-select": "^1.2.2", "beautify": "^0.0.8", "chalk": "^5.3.0", "clsx": "^2.0.0", "date-fns": "^4.1.0", "es-module-lexer": "^1.4.1", "react-d3-tree": "^3.6.2", "react-diff-viewer-continued": "^3.3.1", "react-hotkeys-hook": "^4.5.0", "tailwind-merge": "^1.14.0" }, "peerDependencies": { "@remix-run/react": ">=1.15", "react": ">=17", "react-dom": ">=17", "vite": ">=5.0.0" } }, "sha512-yJlLm1hxhZhLr2Q4CqPyEtaIrg9GsTvU72Eu9moLkR5azVZeVepJcuHwACZJN0vGVdV4eto1IRPljYuODcG4Vw=="],
28402832

28412833
"remix-flat-routes": ["[email protected]", "", { "dependencies": { "fs-extra": "^11.2.0", "minimatch": "^10.0.1" }, "bin": { "migrate-flat-routes": "dist/cli.cjs" } }, "sha512-30GcEpvwqFXCyTKiCTeqI3QSNyTg+f0qLGeIc95y6o3gaOEIhbC37qWpe8HrVEkdnj48xUyaUK03jm1zYFkhfA=="],
@@ -3742,8 +3734,6 @@
37423734

37433735
"oazapfts/typescript": ["[email protected]", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
37443736

3745-
"openid-client/lru-cache": ["[email protected]", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
3746-
37473737
"opentelemetry-instrumentation-remix/@opentelemetry/instrumentation": ["@opentelemetry/[email protected]", "", { "dependencies": { "@opentelemetry/api-logs": "0.52.1", "@types/shimmer": "^1.0.2", "import-in-the-middle": "^1.8.1", "require-in-the-middle": "^7.1.1", "semver": "^7.5.2", "shimmer": "^1.2.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw=="],
37483738

37493739
"ora/chalk": ["[email protected]", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="],
@@ -3790,10 +3780,6 @@
37903780

37913781
"remark-mdx-frontmatter/estree-util-is-identifier-name": ["[email protected]", "", {}, "sha512-OVJZ3fGGt9By77Ix9NhaRbzfbDV/2rx9EP7YIDJTmsZSEc5kYn2vWcNccYyahJL2uAQZK2a5Or2i0wtIKTPoRQ=="],
37923782

3793-
"remix-auth-openid/@mjackson/headers": ["@mjackson/[email protected]", "", {}, "sha512-1WFCu2iRaqbez9hcYYI611vcH1V25R+fDfOge/CyKc8sdbzniGfy/FRhNd3DgvFF4ZEEX2ayBrvFHLtOpfvadw=="],
3794-
3795-
"remix-auth-openid/react-router": ["[email protected]", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-pfAByjcTpX55mqSDGwGnY9vDCpxqBLASg0BMNAuMmpSGESo/TaOUG6BllhAtAkCGx8Rnohik/XtaqiYUJtgW2g=="],
3796-
37973783
"remix-development-tools/@radix-ui/react-select": ["@radix-ui/[email protected]", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/number": "1.0.1", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-collection": "1.0.3", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-direction": "1.0.1", "@radix-ui/react-dismissable-layer": "1.0.4", "@radix-ui/react-focus-guards": "1.0.1", "@radix-ui/react-focus-scope": "1.0.3", "@radix-ui/react-id": "1.0.1", "@radix-ui/react-popper": "1.1.2", "@radix-ui/react-portal": "1.0.3", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-slot": "1.0.2", "@radix-ui/react-use-callback-ref": "1.0.1", "@radix-ui/react-use-controllable-state": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1", "@radix-ui/react-use-previous": "1.0.1", "@radix-ui/react-visually-hidden": "1.0.3", "aria-hidden": "^1.1.1", "react-remove-scroll": "2.5.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw=="],
37983784

37993785
"remix-development-tools/chalk": ["[email protected]", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="],
@@ -4394,8 +4380,6 @@
43944380

43954381
"marble-api/tailwind-preset/tailwindcss/lilconfig": ["[email protected]", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
43964382

4397-
"marble-api/tailwind-preset/tailwindcss/object-hash": ["[email protected]", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
4398-
43994383
"marble-api/tailwind-preset/tailwindcss/postcss-load-config": ["[email protected]", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="],
44004384

44014385
"mdast-util-mdx/mdast-util-from-markdown/micromark/micromark-core-commonmark": ["[email protected]", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-factory-destination": "^1.0.0", "micromark-factory-label": "^1.0.0", "micromark-factory-space": "^1.0.0", "micromark-factory-title": "^1.0.0", "micromark-factory-whitespace": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-chunked": "^1.0.0", "micromark-util-classify-character": "^1.0.0", "micromark-util-html-tag-name": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-resolve-all": "^1.0.0", "micromark-util-subtokenize": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.1", "uvu": "^0.5.0" } }, "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw=="],

packages/app-builder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"@tanstack/react-query-devtools": "5.83.1",
7979
"@tanstack/react-table": "^8.21.2",
8080
"@tanstack/react-virtual": "3.13.12",
81+
"arctic": "^3.7.0",
8182
"autosuggest-highlight": "^3.3.4",
8283
"class-variance-authority": "^0.7.1",
8384
"clsx": "^2.1.1",

packages/app-builder/src/services/auth/oidc.server.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { AppConfigRepository } from '@app-builder/repositories/AppConfigRepository';
22
import { Tokens } from '@app-builder/routes/oidc+/auth';
33
import { getServerEnv } from '@app-builder/utils/environment';
4+
import { OAuth2Tokens } from 'arctic';
45
import { OAuth2Strategy } from 'remix-auth-oauth2';
56

67
let oidcStrategy: MarbleOidcStrategy<Tokens> | undefined = undefined;
@@ -33,13 +34,15 @@ export const makeOidcService = async (configRepository: AppConfigRepository) =>
3334
redirectURI: config.auth.oidc.redirect_uri,
3435
scopes: config.auth.oidc.scopes,
3536
},
36-
async ({ tokens }): Promise<Tokens> => {
37+
async ({ tokens: rawTokens }): Promise<Tokens> => {
38+
const tokens: CompatOAuth2Tokens = new CompatOAuth2Tokens(rawTokens.data);
39+
3740
const credentials: Tokens = {
3841
sub: 'DOES NOT MATTER',
3942
accessToken: tokens.accessToken() ?? '',
4043
refreshToken: tokens.hasRefreshToken() ? tokens.refreshToken() : '',
4144
idToken: tokens.idToken(),
42-
expiredAt: tokens.accessTokenExpiresAt().getTime() ?? 0,
45+
expiredAt: (tokens as CompatOAuth2Tokens).accessTokenExpiresAt().getTime() ?? 0,
4346
};
4447

4548
return credentials;
@@ -50,3 +53,33 @@ export const makeOidcService = async (configRepository: AppConfigRepository) =>
5053

5154
return oidcStrategy;
5255
};
56+
57+
//
58+
// Some OpenID Connect providers do not follow the specification. This class
59+
// extends the one we receive from the IDP to implement more relaxed parsing
60+
// methods in order to accept more kinds of responses.
61+
//
62+
class CompatOAuth2Tokens extends OAuth2Tokens {
63+
// Microsoft Azure's implementation of OpenID Connect sends the `expires_in`
64+
// field as a stringified integer, instead of a real integer. This breaks our
65+
// library, we therefore override their functions in order to parse it anyway.
66+
override accessTokenExpiresInSeconds(): number {
67+
if ('expires_in' in this.data) {
68+
if (typeof this.data.expires_in === 'number') {
69+
return this.data.expires_in;
70+
}
71+
72+
if (typeof this.data.expires_in === 'string') {
73+
const expiresInInt = parseInt(this.data.expires_in);
74+
75+
if (!isNaN(expiresInInt) && expiresInInt.toString() === this.data.expires_in) {
76+
return expiresInInt;
77+
}
78+
79+
return expiresInInt;
80+
}
81+
}
82+
83+
throw new Error("Missing or invalid 'expires_in' field");
84+
}
85+
}

0 commit comments

Comments
 (0)