diff --git a/package.json b/package.json index c6bddbd1..8da88223 100644 --- a/package.json +++ b/package.json @@ -40,12 +40,12 @@ "defu": "^6.1.4", "h3": "^1.14.0", "hookable": "^5.5.3", - "jose": "^5.9.6", "ofetch": "^1.4.1", "openid-client": "^6.1.7", "pathe": "^2.0.2", "scule": "^1.3.0", - "uncrypto": "^0.1.3" + "uncrypto": "^0.1.3", + "unjwt": "^0.5.5" }, "peerDependencies": { "@atproto/api": "^0.13.15", diff --git a/playground/middleware/jwt.global.ts b/playground/middleware/jwt.global.ts index 240b7ee6..1ff8061d 100644 --- a/playground/middleware/jwt.global.ts +++ b/playground/middleware/jwt.global.ts @@ -1,7 +1,7 @@ import { appendResponseHeader } from 'h3' import { parse, parseSetCookie, serialize } from 'cookie-es' -import type { JwtData } from '@tsndr/cloudflare-worker-jwt' -import { decode } from '@tsndr/cloudflare-worker-jwt' +import type { JWSVerifyResult, JWTClaims } from 'unjwt' +import { jws } from 'unjwt' export default defineNuxtRouteMiddleware(async () => { const nuxtApp = useNuxtApp() @@ -16,17 +16,26 @@ export default defineNuxtRouteMiddleware(async () => { const runtimeConfig = useRuntimeConfig() const { accessToken, refreshToken } = session.value.jwt - const accessPayload = decode(accessToken) - const refreshPayload = decode(refreshToken) + // For demo purposes only, use high entropy secrets or keys in production + const accessTokenKey = new TextEncoder().encode(process.env.NUXT_SESSION_PASSWORD) + const refreshTokenKey = new TextEncoder().encode(`${process.env.NUXT_SESSION_PASSWORD}-secret`) + + const [ + verifiedAccessToken, + verifiedRefreshToken, + ] = await Promise.all([ + jws.verify(accessToken, accessTokenKey), + jws.verify(refreshToken, refreshTokenKey), + ]) // Both tokens expired, clearing session - if (isExpired(accessPayload) && isExpired(refreshPayload)) { + if (isExpired(verifiedAccessToken) && isExpired(verifiedRefreshToken)) { console.info('both tokens expired, clearing session') await clearSession() // return navigateTo('/login') } // Access token expired, refreshing - else if (isExpired(accessPayload)) { + else if (isExpired(verifiedAccessToken)) { console.info('access token expired, refreshing') await useRequestFetch()('/api/jwt/refresh', { method: 'POST', @@ -58,6 +67,6 @@ export default defineNuxtRouteMiddleware(async () => { } }) -function isExpired(payload: JwtData) { +function isExpired(payload: JWSVerifyResult) { return payload.payload?.exp && payload.payload.exp < (Date.now() / 1000) } diff --git a/playground/package.json b/playground/package.json index bfc7807f..c015b423 100644 --- a/playground/package.json +++ b/playground/package.json @@ -11,7 +11,6 @@ "@iconify-json/gravity-ui": "^1.2.4", "@iconify-json/iconoir": "^1.2.7", "@iconify-json/logos": "^1.2.4", - "@tsndr/cloudflare-worker-jwt": "^3.1.3", "@vueuse/core": "^12.5.0", "@vueuse/nuxt": "^12.5.0", "nuxt": "^3.15.4", diff --git a/playground/server/api/jwt/create.post.ts b/playground/server/api/jwt/create.post.ts index 4cc24467..8b60c587 100644 --- a/playground/server/api/jwt/create.post.ts +++ b/playground/server/api/jwt/create.post.ts @@ -1,4 +1,4 @@ -import jwt from '@tsndr/cloudflare-worker-jwt' +import { jws } from 'unjwt' export default defineEventHandler(async (event) => { // Get user from session @@ -17,20 +17,26 @@ export default defineEventHandler(async (event) => { }) } + // For demo purposes only, use high entropy secrets or keys in production + const accessTokenKey = new TextEncoder().encode(process.env.NUXT_SESSION_PASSWORD) + const refreshTokenKey = new TextEncoder().encode(`${process.env.NUXT_SESSION_PASSWORD}-secret`) + // Generate tokens - const accessToken = await jwt.sign( + const accessToken = await jws.sign( { hello: 'world', exp: Math.floor(Date.now() / 1000) + 5, // 30 seconds }, - process.env.NUXT_SESSION_PASSWORD, + accessTokenKey, + { alg: 'HS256' }, ) - const refreshToken = await jwt.sign( + const refreshToken = await jws.sign( { exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, // 7 days }, - `${process.env.NUXT_SESSION_PASSWORD}-secret`, + refreshTokenKey, + { alg: 'HS256' }, ) await setUserSession(event, { diff --git a/playground/server/api/jwt/payload.get.ts b/playground/server/api/jwt/payload.get.ts index 4fc042fc..3ea08b9c 100644 --- a/playground/server/api/jwt/payload.get.ts +++ b/playground/server/api/jwt/payload.get.ts @@ -1,4 +1,4 @@ -import jwt from '@tsndr/cloudflare-worker-jwt' +import { verify } from 'unjwt/jws' export default eventHandler(async (event) => { const session = await getUserSession(event) @@ -9,10 +9,11 @@ export default eventHandler(async (event) => { }) } + // For demo purposes only, use a high entropy secret or key in production + const accessTokenKey = new TextEncoder().encode(process.env.NUXT_SESSION_PASSWORD) + try { - return await jwt.verify(session.jwt.accessToken, process.env.NUXT_SESSION_PASSWORD!, { - throwError: true, - }) + return await verify(session.jwt.accessToken, accessTokenKey) } catch (err) { throw createError({ diff --git a/playground/server/api/jwt/refresh.post.ts b/playground/server/api/jwt/refresh.post.ts index efd2f5a5..ac4bf972 100644 --- a/playground/server/api/jwt/refresh.post.ts +++ b/playground/server/api/jwt/refresh.post.ts @@ -1,4 +1,5 @@ -import jwt from '@tsndr/cloudflare-worker-jwt' +import type { JWSVerifyResult, JWTClaims } from 'unjwt' +import { sign, verify } from 'unjwt/jws' export default eventHandler(async (event) => { const session = await getUserSession(event) @@ -9,19 +10,28 @@ export default eventHandler(async (event) => { }) } - if (!await jwt.verify(session.jwt.refreshToken, `${process.env.NUXT_SESSION_PASSWORD!}-secret`)) { + // For demo purposes only, use high entropy secrets or keys in production + const accessTokenKey = new TextEncoder().encode(process.env.NUXT_SESSION_PASSWORD) + const refreshTokenKey = new TextEncoder().encode(`${process.env.NUXT_SESSION_PASSWORD}-secret`) + + const verifiedRefreshToken = await verify(session.jwt.refreshToken, refreshTokenKey).catch(() => false as const) + + if (!verifiedRefreshToken || isExpired(verifiedRefreshToken)) { throw createError({ statusCode: 401, message: 'refresh token is invalid', }) } - const accessToken = await jwt.sign( + const accessToken = await sign( { hello: 'world', exp: Math.floor(Date.now() / 1000) + 30, // 30 seconds }, - process.env.NUXT_SESSION_PASSWORD!, + accessTokenKey, + { + alg: 'HS256', + }, ) await setUserSession(event, { @@ -37,3 +47,7 @@ export default eventHandler(async (event) => { refreshToken: session.jwt.refreshToken, } }) + +function isExpired(payload: JWSVerifyResult) { + return payload.payload?.exp && payload.payload.exp < (Date.now() / 1000) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6be740ce..a409707c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: 0.2.0 '@nuxt/kit': specifier: ^3.15.4 - version: 3.15.4(magicast@0.3.5)(rollup@3.29.4) + version: 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@simplewebauthn/browser': specifier: ^11.0.0 version: 11.0.0 @@ -35,9 +35,6 @@ importers: hookable: specifier: ^5.5.3 version: 5.5.3 - jose: - specifier: ^5.9.6 - version: 5.9.6 ofetch: specifier: ^1.4.1 version: 1.4.1 @@ -53,31 +50,34 @@ importers: uncrypto: specifier: ^0.1.3 version: 0.1.3 + unjwt: + specifier: ^0.5.5 + version: 0.5.5 devDependencies: '@iconify-json/simple-icons': specifier: ^1.2.23 version: 1.2.23 '@nuxt/devtools': specifier: 2.0.0-beta.7 - version: 2.0.0-beta.7(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) + version: 2.0.0-beta.7(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@nuxt/eslint-config': specifier: ^0.7.6 version: 0.7.6(@vue/compiler-sfc@3.5.13)(eslint@9.19.0(jiti@2.4.2))(typescript@5.6.3) '@nuxt/module-builder': specifier: ^0.8.4 - version: 0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(nuxi@3.15.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3)) + version: 0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4))(nuxi@3.15.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3)) '@nuxt/schema': specifier: ^3.15.4 version: 3.15.4 '@nuxt/test-utils': specifier: ^3.15.4 - version: 3.15.4(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0) + version: 3.15.4(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0) '@nuxt/ui': specifier: ^2.21.0 - version: 2.21.0(change-case@5.4.4)(magicast@0.3.5)(rollup@3.29.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) + version: 2.21.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.24.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@nuxt/ui-pro': specifier: ^1.7.0 - version: 1.7.0(change-case@5.4.4)(magicast@0.3.5)(rollup@3.29.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) + version: 1.7.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.24.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@simplewebauthn/types': specifier: ^11.0.0 version: 11.0.0 @@ -89,7 +89,7 @@ importers: version: 9.19.0(jiti@2.4.2) nuxt: specifier: ^3.15.4 - version: 3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0) + version: 3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0) typescript: specifier: 5.6.3 version: 5.6.3 @@ -111,21 +111,18 @@ importers: '@iconify-json/logos': specifier: ^1.2.4 version: 1.2.4 - '@tsndr/cloudflare-worker-jwt': - specifier: ^3.1.3 - version: 3.1.3 '@vueuse/core': specifier: ^12.5.0 version: 12.5.0(typescript@5.6.3) '@vueuse/nuxt': specifier: ^12.5.0 - version: 12.5.0(magicast@0.3.5)(nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3))(yaml@2.7.0))(rollup@4.24.4)(typescript@5.6.3) + version: 12.5.0(magicast@0.3.5)(nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0))(rollup@4.24.4)(typescript@5.6.3) nuxt: specifier: ^3.15.4 - version: 3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3))(yaml@2.7.0) + version: 3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0) nuxt-auth-utils: specifier: latest - version: 0.5.19(@atproto/api@0.13.15)(@atproto/oauth-client-node@0.2.0)(@simplewebauthn/browser@11.0.0)(@simplewebauthn/server@11.0.0)(magicast@0.3.5)(rollup@4.24.4) + version: 0.5.20(@atproto/api@0.13.15)(@atproto/oauth-client-node@0.2.0)(@simplewebauthn/browser@11.0.0)(@simplewebauthn/server@11.0.0)(magicast@0.3.5)(rollup@4.24.4) zod: specifier: ^3.24.1 version: 3.24.1 @@ -1745,9 +1742,6 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tsndr/cloudflare-worker-jwt@3.1.3': - resolution: {integrity: sha512-ohuQzCICeki6wBOtmyqk0JJyJvl4vE1/RgXModJzm2U3xfiFNbkXtpa2HHGiH9BG7Wd/G7mtu2xtJ1R8W6iP5w==} - '@types/bytes@3.1.4': resolution: {integrity: sha512-A0uYgOj3zNc4hNjHc5lYUfJQ/HVyBXiUMKdXd7ysclaE6k9oJdavQzODHuwjpUu2/boCP8afjQYi8z/GtvNCWA==} @@ -1997,14 +1991,6 @@ packages: '@vue/devtools-shared@7.7.1': resolution: {integrity: sha512-BtgF7kHq4BHG23Lezc/3W2UhK2ga7a8ohAIAGJMBr4BkxUFzhqntQtCiuL1ijo2ztWnmusymkirgqUrXoQKumA==} - '@vue/language-core@2.1.10': - resolution: {integrity: sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@vue/language-core@2.2.0': resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} peerDependencies: @@ -2133,9 +2119,6 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - alien-signals@0.2.2: - resolution: {integrity: sha512-cZIRkbERILsBOXTQmMrxc9hgpxglstn69zm+F1ARf4aPAzdAFYd6sBq87ErO0Fj3DV94tglcyHG5kQz9nDC/8A==} - alien-signals@0.4.14: resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} @@ -4015,8 +3998,8 @@ packages: engines: {node: ^16.10.0 || >=18.0.0} hasBin: true - nuxt-auth-utils@0.5.19: - resolution: {integrity: sha512-cI4ckY/BniwjWmF13jGni8rtaepi5b5eR05/wjCHB9gZlmIJPmDSchHZf8+GChP9CohOZt1pX2y+AqAjxgzmAw==} + nuxt-auth-utils@0.5.20: + resolution: {integrity: sha512-hoXopfYeK4Cdu17WxxDWYc66EH7ZYG8JUodPxxef9vjfXOXqz3s1gxi/JWsiqkwN6s7K1RpKEESZGg1EopCgAA==} peerDependencies: '@atproto/api': ^0.13.15 '@atproto/oauth-client-node': ^0.2.0 @@ -5205,6 +5188,9 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unjwt@0.5.5: + resolution: {integrity: sha512-YMo7f4K77EsyVKSgDuE9APx3o6kWqu6rW9RIKNUwfTc6aBayeoD094S8uMKhXGXoo3vDeRXvTPaXgNuSUUvQxA==} + unplugin-vue-router@0.11.2: resolution: {integrity: sha512-X8BbQ3BNnMqaCYeMj80jtz5jC4AB0jcpdmECIYey9qKm6jy/upaPZ/WzfuT+iTGRiQAY4WemHueXxuzH127oOg==} peerDependencies: @@ -5559,12 +5545,6 @@ packages: peerDependencies: vue: ^3.2.0 - vue-tsc@2.1.10: - resolution: {integrity: sha512-RBNSfaaRHcN5uqVqJSZh++Gy/YUzryuv9u1aFWhsammDJXNtUiJMNoJ747lZcQ68wUQFx6E73y4FY3D8E7FGMA==} - hasBin: true - peerDependencies: - typescript: '>=5.0.0' - vue-tsc@2.2.0: resolution: {integrity: sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==} hasBin: true @@ -6752,9 +6732,9 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))': + '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))': dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@nuxt/schema': 3.15.4 execa: 7.2.0 vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) @@ -6763,21 +6743,10 @@ snapshots: - rollup - supports-color - '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@4.24.4)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))': + '@nuxt/devtools-kit@2.0.0-beta.7(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@nuxt/schema': 3.15.4 - execa: 7.2.0 - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - transitivePeerDependencies: - - magicast - - rollup - - supports-color - - '@nuxt/devtools-kit@2.0.0-beta.7(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))': - dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) - '@nuxt/schema': 3.15.4 execa: 9.5.2 vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) transitivePeerDependencies: @@ -6809,12 +6778,12 @@ snapshots: prompts: 2.4.2 semver: 7.7.1 - '@nuxt/devtools@1.7.0(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': + '@nuxt/devtools@1.7.0(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': dependencies: '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) + '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) '@nuxt/devtools-wizard': 1.7.0 - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@vue/devtools-core': 7.6.8(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@vue/devtools-kit': 7.6.8 birpc: 0.2.19 @@ -6843,9 +6812,9 @@ snapshots: simple-git: 3.27.0 sirv: 3.0.0 tinyglobby: 0.2.10 - unimport: 3.14.6(rollup@3.29.4) + unimport: 3.14.6(rollup@4.24.4) vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) - vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) + vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4))(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) vite-plugin-vue-inspector: 5.3.1(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) which: 3.0.1 ws: 8.18.0 @@ -6856,58 +6825,11 @@ snapshots: - utf-8-validate - vue - '@nuxt/devtools@1.7.0(rollup@4.24.4)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.3))': - dependencies: - '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.24.4)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)) - '@nuxt/devtools-wizard': 1.7.0 - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) - '@vue/devtools-core': 7.6.8(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.3)) - '@vue/devtools-kit': 7.6.8 - birpc: 0.2.19 - consola: 3.4.0 - cronstrue: 2.53.0 - destr: 2.0.3 - error-stack-parser-es: 0.1.5 - execa: 7.2.0 - fast-npm-meta: 0.2.2 - flatted: 3.3.2 - get-port-please: 3.1.2 - hookable: 5.5.3 - image-meta: 0.2.1 - is-installed-globally: 1.0.0 - launch-editor: 2.9.1 - local-pkg: 0.5.1 - magicast: 0.3.5 - nypm: 0.4.1 - ohash: 1.1.4 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.1 - rc9: 2.1.2 - scule: 1.3.0 - semver: 7.7.1 - simple-git: 3.27.0 - sirv: 3.0.0 - tinyglobby: 0.2.10 - unimport: 3.14.6(rollup@4.24.4) - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(rollup@4.24.4)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)) - vite-plugin-vue-inspector: 5.3.1(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)) - which: 3.0.1 - ws: 8.18.0 - transitivePeerDependencies: - - bufferutil - - rollup - - supports-color - - utf-8-validate - - vue - - '@nuxt/devtools@2.0.0-beta.7(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': + '@nuxt/devtools@2.0.0-beta.7(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': dependencies: - '@nuxt/devtools-kit': 2.0.0-beta.7(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) + '@nuxt/devtools-kit': 2.0.0-beta.7(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) '@nuxt/devtools-wizard': 2.0.0-beta.7 - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@vue/devtools-core': 7.7.1(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@vue/devtools-kit': 7.7.1 birpc: 2.2.0 @@ -6934,7 +6856,7 @@ snapshots: structured-clone-es: 1.0.0 tinyglobby: 0.2.10 vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) - vite-plugin-inspect: 10.1.0(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) + vite-plugin-inspect: 10.1.0(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4))(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) vite-plugin-vue-inspector: 5.3.1(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) which: 5.0.0 ws: 8.18.0 @@ -6982,14 +6904,14 @@ snapshots: - supports-color - typescript - '@nuxt/icon@1.10.3(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': + '@nuxt/icon@1.10.3(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': dependencies: '@iconify/collections': 1.0.510 '@iconify/types': 2.0.0 '@iconify/utils': 2.2.1 '@iconify/vue': 4.3.0(vue@3.5.13(typescript@5.6.3)) - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) consola: 3.2.3 local-pkg: 0.5.1 mlly: 1.7.4 @@ -7005,33 +6927,6 @@ snapshots: - vite - vue - '@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4)': - dependencies: - c12: 2.0.1(magicast@0.3.5) - consola: 3.4.0 - defu: 6.1.4 - destr: 2.0.3 - globby: 14.0.2 - ignore: 7.0.3 - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - mlly: 1.7.4 - ohash: 1.1.4 - pathe: 2.0.2 - pkg-types: 1.3.1 - scule: 1.3.0 - semver: 7.6.3 - std-env: 3.8.0 - ufo: 1.5.4 - unctx: 2.4.1 - unimport: 4.0.0(rollup@3.29.4) - untyped: 1.5.2 - transitivePeerDependencies: - - magicast - - rollup - - supports-color - '@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4)': dependencies: c12: 2.0.1(magicast@0.3.5) @@ -7059,9 +6954,9 @@ snapshots: - rollup - supports-color - '@nuxt/module-builder@0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(nuxi@3.15.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3))': + '@nuxt/module-builder@0.8.4(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4))(nuxi@3.15.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3))': dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) citty: 0.1.6 consola: 3.2.3 defu: 6.1.4 @@ -7086,26 +6981,6 @@ snapshots: pathe: 2.0.2 std-env: 3.8.0 - '@nuxt/telemetry@2.6.4(magicast@0.3.5)(rollup@3.29.4)': - dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) - citty: 0.1.6 - consola: 3.4.0 - destr: 2.0.3 - dotenv: 16.4.7 - git-url-parse: 16.0.0 - is-docker: 3.0.0 - ofetch: 1.4.1 - package-manager-detector: 0.2.8 - parse-git-config: 3.0.0 - pathe: 2.0.2 - rc9: 2.1.2 - std-env: 3.8.0 - transitivePeerDependencies: - - magicast - - rollup - - supports-color - '@nuxt/telemetry@2.6.4(magicast@0.3.5)(rollup@4.24.4)': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) @@ -7126,9 +7001,9 @@ snapshots: - rollup - supports-color - '@nuxt/test-utils@3.15.4(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0)': + '@nuxt/test-utils@3.15.4(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0)': dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@nuxt/schema': 3.15.4 c12: 2.0.1(magicast@0.3.5) consola: 3.4.0 @@ -7152,7 +7027,7 @@ snapshots: unenv: 1.10.0 unplugin: 2.1.2 vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - vitest-environment-nuxt: 1.0.1(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0) + vitest-environment-nuxt: 1.0.1(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0) vue: 3.5.13(typescript@5.6.3) optionalDependencies: vitest: 3.0.5(@types/node@22.5.5)(terser@5.33.0) @@ -7173,10 +7048,10 @@ snapshots: - typescript - yaml - '@nuxt/ui-pro@1.7.0(change-case@5.4.4)(magicast@0.3.5)(rollup@3.29.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': + '@nuxt/ui-pro@1.7.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.24.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': dependencies: '@iconify-json/vscode-icons': 1.2.10 - '@nuxt/ui': 2.21.0(change-case@5.4.4)(magicast@0.3.5)(rollup@3.29.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) + '@nuxt/ui': 2.21.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.24.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@vueuse/core': 12.5.0(typescript@5.6.3) defu: 6.1.4 git-url-parse: 16.0.0 @@ -7206,15 +7081,15 @@ snapshots: - vite - vue - '@nuxt/ui@2.21.0(change-case@5.4.4)(magicast@0.3.5)(rollup@3.29.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': + '@nuxt/ui@2.21.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.24.4)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': dependencies: '@headlessui/tailwindcss': 0.2.1(tailwindcss@3.4.17) '@headlessui/vue': 1.7.23(vue@3.5.13(typescript@5.6.3)) '@iconify-json/heroicons': 1.2.2 - '@nuxt/icon': 1.10.3(magicast@0.3.5)(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) - '@nuxtjs/color-mode': 3.5.2(magicast@0.3.5)(rollup@3.29.4) - '@nuxtjs/tailwindcss': 6.13.1(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/icon': 1.10.3(magicast@0.3.5)(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) + '@nuxtjs/color-mode': 3.5.2(magicast@0.3.5)(rollup@4.24.4) + '@nuxtjs/tailwindcss': 6.13.1(magicast@0.3.5)(rollup@4.24.4) '@popperjs/core': 2.11.8 '@tailwindcss/aspect-ratio': 0.4.2(tailwindcss@3.4.17) '@tailwindcss/container-queries': 0.1.1(tailwindcss@3.4.17) @@ -7250,66 +7125,7 @@ snapshots: - vite - vue - '@nuxt/vite-builder@3.15.4(@types/node@22.5.5)(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))(yaml@2.7.0)': - dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) - '@rollup/plugin-replace': 6.0.2(rollup@3.29.4) - '@vitejs/plugin-vue': 5.2.1(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.3)) - '@vitejs/plugin-vue-jsx': 4.1.1(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.3)) - autoprefixer: 10.4.20(postcss@8.5.1) - consola: 3.4.0 - cssnano: 7.0.6(postcss@8.5.1) - defu: 6.1.4 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - externality: 1.0.2 - get-port-please: 3.1.2 - h3: 1.14.0 - jiti: 2.4.2 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.4 - ohash: 1.1.4 - pathe: 2.0.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.1 - postcss: 8.5.1 - rollup-plugin-visualizer: 5.14.0(rollup@3.29.4) - std-env: 3.8.0 - ufo: 1.5.4 - unenv: 1.10.0 - unplugin: 2.1.2 - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - vite-node: 3.0.5(@types/node@22.5.5)(terser@5.33.0) - vite-plugin-checker: 0.8.0(eslint@9.19.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.6.3)) - vue: 3.5.13(typescript@5.6.3) - vue-bundle-renderer: 2.1.1 - transitivePeerDependencies: - - '@biomejs/biome' - - '@types/node' - - eslint - - less - - lightningcss - - magicast - - meow - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - vls - - vti - - vue-tsc - - yaml - - '@nuxt/vite-builder@3.15.4(@types/node@22.5.5)(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))(yaml@2.7.0)': + '@nuxt/vite-builder@3.15.4(@types/node@22.5.5)(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))(yaml@2.7.0)': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@rollup/plugin-replace': 6.0.2(rollup@4.24.4) @@ -7340,7 +7156,7 @@ snapshots: unplugin: 2.1.2 vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) vite-node: 3.0.5(@types/node@22.5.5)(terser@5.33.0) - vite-plugin-checker: 0.8.0(eslint@9.19.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3)) + vite-plugin-checker: 0.8.0(eslint@9.19.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.6.3)) vue: 3.5.13(typescript@5.6.3) vue-bundle-renderer: 2.1.1 transitivePeerDependencies: @@ -7368,9 +7184,9 @@ snapshots: - vue-tsc - yaml - '@nuxtjs/color-mode@3.5.2(magicast@0.3.5)(rollup@3.29.4)': + '@nuxtjs/color-mode@3.5.2(magicast@0.3.5)(rollup@4.24.4)': dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) pathe: 1.1.2 pkg-types: 1.2.1 semver: 7.6.3 @@ -7379,9 +7195,9 @@ snapshots: - rollup - supports-color - '@nuxtjs/tailwindcss@6.13.1(magicast@0.3.5)(rollup@3.29.4)': + '@nuxtjs/tailwindcss@6.13.1(magicast@0.3.5)(rollup@4.24.4)': dependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) autoprefixer: 10.4.20(postcss@8.5.1) c12: 2.0.1(magicast@0.3.5) consola: 3.4.0 @@ -7628,13 +7444,6 @@ snapshots: optionalDependencies: rollup: 3.29.4 - '@rollup/plugin-replace@6.0.2(rollup@3.29.4)': - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@3.29.4) - magic-string: 0.30.17 - optionalDependencies: - rollup: 3.29.4 - '@rollup/plugin-replace@6.0.2(rollup@4.24.4)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.24.4) @@ -7671,14 +7480,6 @@ snapshots: optionalDependencies: rollup: 4.24.4 - '@rollup/pluginutils@5.1.4(rollup@3.29.4)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 3.29.4 - '@rollup/pluginutils@5.1.4(rollup@4.24.4)': dependencies: '@types/estree': 1.0.6 @@ -7809,8 +7610,6 @@ snapshots: '@trysound/sax@0.2.0': {} - '@tsndr/cloudflare-worker-jwt@3.1.3': {} - '@types/bytes@3.1.4': {} '@types/doctrine@0.0.9': {} @@ -8196,18 +7995,6 @@ snapshots: transitivePeerDependencies: - vite - '@vue/devtools-core@7.6.8(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.3))': - dependencies: - '@vue/devtools-kit': 7.7.1 - '@vue/devtools-shared': 7.7.1 - mitt: 3.0.1 - nanoid: 5.0.9 - pathe: 1.1.2 - vite-hot-client: 0.2.4(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)) - vue: 3.5.13(typescript@5.6.3) - transitivePeerDependencies: - - vite - '@vue/devtools-core@7.7.1(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3))': dependencies: '@vue/devtools-kit': 7.7.1 @@ -8244,20 +8031,6 @@ snapshots: dependencies: rfdc: 1.4.1 - '@vue/language-core@2.1.10(typescript@5.6.3)': - dependencies: - '@volar/language-core': 2.4.11 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.13 - alien-signals: 0.2.2 - minimatch: 9.0.5 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - optionalDependencies: - typescript: 5.6.3 - optional: true - '@vue/language-core@2.2.0(typescript@5.6.3)': dependencies: '@volar/language-core': 2.4.11 @@ -8326,13 +8099,13 @@ snapshots: '@vueuse/metadata@12.5.0': {} - '@vueuse/nuxt@12.5.0(magicast@0.3.5)(nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3))(yaml@2.7.0))(rollup@4.24.4)(typescript@5.6.3)': + '@vueuse/nuxt@12.5.0(magicast@0.3.5)(nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0))(rollup@4.24.4)(typescript@5.6.3)': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@vueuse/core': 12.5.0(typescript@5.6.3) '@vueuse/metadata': 12.5.0 local-pkg: 1.0.0 - nuxt: 3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3))(yaml@2.7.0) + nuxt: 3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0) vue: 3.5.13(typescript@5.6.3) transitivePeerDependencies: - magicast @@ -8388,9 +8161,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - alien-signals@0.2.2: - optional: true - alien-signals@0.4.14: {} ansi-colors@4.1.3: {} @@ -9856,16 +9626,6 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - impound@0.2.0(rollup@3.29.4): - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@3.29.4) - mlly: 1.7.4 - pathe: 1.1.2 - unenv: 1.10.0 - unplugin: 1.16.1 - transitivePeerDependencies: - - rollup - impound@0.2.0(rollup@4.24.4): dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.24.4) @@ -10539,7 +10299,7 @@ snapshots: nuxi@3.15.0: {} - nuxt-auth-utils@0.5.19(@atproto/api@0.13.15)(@atproto/oauth-client-node@0.2.0)(@simplewebauthn/browser@11.0.0)(@simplewebauthn/server@11.0.0)(magicast@0.3.5)(rollup@4.24.4): + nuxt-auth-utils@0.5.20(@atproto/api@0.13.15)(@atproto/oauth-client-node@0.2.0)(@simplewebauthn/browser@11.0.0)(@simplewebauthn/server@11.0.0)(magicast@0.3.5)(rollup@4.24.4): dependencies: '@adonisjs/hash': 9.0.5 '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) @@ -10564,15 +10324,15 @@ snapshots: - rollup - supports-color - nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3))(yaml@2.7.0): + nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0): dependencies: '@nuxt/cli': 3.21.1(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@4.24.4)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.3)) + '@nuxt/devtools': 1.7.0(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) '@nuxt/schema': 3.15.4 '@nuxt/telemetry': 2.6.4(magicast@0.3.5)(rollup@4.24.4) - '@nuxt/vite-builder': 3.15.4(@types/node@22.5.5)(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))(yaml@2.7.0) + '@nuxt/vite-builder': 3.15.4(@types/node@22.5.5)(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))(yaml@2.7.0) '@unhead/dom': 1.11.18 '@unhead/shared': 1.11.18 '@unhead/ssr': 1.11.18 @@ -10685,127 +10445,6 @@ snapshots: - xml2js - yaml - nuxt@3.15.4(@parcel/watcher@2.4.1)(@types/node@22.5.5)(better-sqlite3@11.8.1)(db0@0.2.1(better-sqlite3@11.8.1))(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue-tsc@2.2.0(typescript@5.6.3))(yaml@2.7.0): - dependencies: - '@nuxt/cli': 3.21.1(magicast@0.3.5) - '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0))(vue@3.5.13(typescript@5.6.3)) - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) - '@nuxt/schema': 3.15.4 - '@nuxt/telemetry': 2.6.4(magicast@0.3.5)(rollup@3.29.4) - '@nuxt/vite-builder': 3.15.4(@types/node@22.5.5)(eslint@9.19.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vue-tsc@2.2.0(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))(yaml@2.7.0) - '@unhead/dom': 1.11.18 - '@unhead/shared': 1.11.18 - '@unhead/ssr': 1.11.18 - '@unhead/vue': 1.11.18(vue@3.5.13(typescript@5.6.3)) - '@vue/shared': 3.5.13 - acorn: 8.14.0 - c12: 2.0.1(magicast@0.3.5) - chokidar: 4.0.3 - compatx: 0.1.8 - consola: 3.4.0 - cookie-es: 1.2.2 - defu: 6.1.4 - destr: 2.0.3 - devalue: 5.1.1 - errx: 0.1.0 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - globby: 14.0.2 - h3: 1.14.0 - hookable: 5.5.3 - ignore: 7.0.3 - impound: 0.2.0(rollup@3.29.4) - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.4 - nanotar: 0.2.0 - nitropack: 2.10.4(better-sqlite3@11.8.1)(typescript@5.6.3) - nypm: 0.5.2 - ofetch: 1.4.1 - ohash: 1.1.4 - pathe: 2.0.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.1 - radix3: 1.1.2 - scule: 1.3.0 - semver: 7.7.1 - std-env: 3.8.0 - strip-literal: 3.0.0 - tinyglobby: 0.2.10 - ufo: 1.5.4 - ultrahtml: 1.5.3 - uncrypto: 0.1.3 - unctx: 2.4.1 - unenv: 1.10.0 - unhead: 1.11.18 - unimport: 4.0.0(rollup@3.29.4) - unplugin: 2.1.2 - unplugin-vue-router: 0.11.2(rollup@3.29.4)(vue-router@4.5.0(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3)) - unstorage: 1.14.4(db0@0.2.1(better-sqlite3@11.8.1))(ioredis@5.4.1) - untyped: 1.5.2 - vue: 3.5.13(typescript@5.6.3) - vue-bundle-renderer: 2.1.1 - vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.13(typescript@5.6.3)) - optionalDependencies: - '@parcel/watcher': 2.4.1 - '@types/node': 22.5.5 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@biomejs/biome' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - bufferutil - - db0 - - drizzle-orm - - encoding - - eslint - - idb-keyval - - ioredis - - less - - lightningcss - - magicast - - meow - - mysql2 - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - uploadthing - - utf-8-validate - - vite - - vls - - vti - - vue-tsc - - xml2js - - yaml - nypm@0.3.12: dependencies: citty: 0.1.6 @@ -11588,15 +11227,6 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.24.7 - rollup-plugin-visualizer@5.14.0(rollup@3.29.4): - dependencies: - open: 8.4.2 - picomatch: 4.0.2 - source-map: 0.7.4 - yargs: 17.7.2 - optionalDependencies: - rollup: 3.29.4 - rollup-plugin-visualizer@5.14.0(rollup@4.24.4): dependencies: open: 8.4.2 @@ -12164,25 +11794,6 @@ snapshots: unicorn-magic@0.3.0: {} - unimport@3.14.6(rollup@3.29.4): - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@3.29.4) - acorn: 8.14.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - fast-glob: 3.3.3 - local-pkg: 1.0.0 - magic-string: 0.30.17 - mlly: 1.7.4 - pathe: 2.0.2 - picomatch: 4.0.2 - pkg-types: 1.3.1 - scule: 1.3.0 - strip-literal: 2.1.1 - unplugin: 1.16.1 - transitivePeerDependencies: - - rollup - unimport@3.14.6(rollup@4.24.4): dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.24.4) @@ -12202,25 +11813,6 @@ snapshots: transitivePeerDependencies: - rollup - unimport@4.0.0(rollup@3.29.4): - dependencies: - '@rollup/pluginutils': 5.1.4(rollup@3.29.4) - acorn: 8.14.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - fast-glob: 3.3.3 - local-pkg: 1.0.0 - magic-string: 0.30.17 - mlly: 1.7.4 - pathe: 2.0.2 - picomatch: 4.0.2 - pkg-types: 1.3.1 - scule: 1.3.0 - strip-literal: 3.0.0 - unplugin: 2.1.2 - transitivePeerDependencies: - - rollup - unimport@4.0.0(rollup@4.24.4): dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.24.4) @@ -12242,27 +11834,7 @@ snapshots: universalify@2.0.1: {} - unplugin-vue-router@0.11.2(rollup@3.29.4)(vue-router@4.5.0(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3)): - dependencies: - '@babel/types': 7.26.7 - '@rollup/pluginutils': 5.1.4(rollup@3.29.4) - '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.6.3)) - ast-walker-scope: 0.6.2 - chokidar: 3.6.0 - fast-glob: 3.3.3 - json5: 2.2.3 - local-pkg: 1.0.0 - magic-string: 0.30.17 - mlly: 1.7.4 - pathe: 2.0.2 - scule: 1.3.0 - unplugin: 2.1.2 - yaml: 2.7.0 - optionalDependencies: - vue-router: 4.5.0(vue@3.5.13(typescript@5.6.3)) - transitivePeerDependencies: - - rollup - - vue + unjwt@0.5.5: {} unplugin-vue-router@0.11.2(rollup@4.24.4)(vue-router@4.5.0(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3)): dependencies: @@ -12396,10 +11968,6 @@ snapshots: dependencies: vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) - vite-hot-client@0.2.4(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)): - dependencies: - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - vite-node@3.0.5(@types/node@22.5.5)(terser@5.33.0): dependencies: cac: 6.7.14 @@ -12418,29 +11986,6 @@ snapshots: - supports-color - terser - vite-plugin-checker@0.8.0(eslint@9.19.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.1.10(typescript@5.6.3)): - dependencies: - '@babel/code-frame': 7.26.2 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - chokidar: 3.6.0 - commander: 8.3.0 - fast-glob: 3.3.3 - fs-extra: 11.3.0 - npm-run-path: 4.0.1 - strip-ansi: 6.0.1 - tiny-invariant: 1.3.3 - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - vscode-languageclient: 7.0.0 - vscode-languageserver: 7.0.0 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 - optionalDependencies: - eslint: 9.19.0(jiti@2.4.2) - optionator: 0.9.4 - typescript: 5.6.3 - vue-tsc: 2.1.10(typescript@5.6.3) - vite-plugin-checker@0.8.0(eslint@9.19.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.3)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.6.3)): dependencies: '@babel/code-frame': 7.26.2 @@ -12464,25 +12009,7 @@ snapshots: typescript: 5.6.3 vue-tsc: 2.2.0(typescript@5.6.3) - vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(rollup@3.29.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)): - dependencies: - '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.4(rollup@3.29.4) - debug: 4.4.0(supports-color@9.4.0) - error-stack-parser-es: 0.1.5 - fs-extra: 11.3.0 - open: 10.1.0 - perfect-debounce: 1.0.0 - picocolors: 1.1.1 - sirv: 3.0.0 - vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) - optionalDependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) - transitivePeerDependencies: - - rollup - - supports-color - - vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(rollup@4.24.4)(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)): + vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4))(rollup@4.24.4)(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.4(rollup@4.24.4) @@ -12493,14 +12020,14 @@ snapshots: perfect-debounce: 1.0.0 picocolors: 1.1.1 sirv: 3.0.0 - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) + vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) optionalDependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) transitivePeerDependencies: - rollup - supports-color - vite-plugin-inspect@10.1.0(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@3.29.4))(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)): + vite-plugin-inspect@10.1.0(@nuxt/kit@3.15.4(magicast@0.3.5)(rollup@4.24.4))(vite@5.4.10(@types/node@22.5.5)(terser@5.33.0)): dependencies: debug: 4.4.0(supports-color@9.4.0) error-stack-parser-es: 1.0.5 @@ -12509,7 +12036,7 @@ snapshots: sirv: 3.0.0 vite: 5.4.10(@types/node@22.5.5)(terser@5.33.0) optionalDependencies: - '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@3.29.4) + '@nuxt/kit': 3.15.4(magicast@0.3.5)(rollup@4.24.4) transitivePeerDependencies: - supports-color @@ -12528,21 +12055,6 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-vue-inspector@5.3.1(vite@6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0)): - dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.26.0) - '@babel/plugin-syntax-import-attributes': 7.25.6(@babel/core@7.26.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.0) - '@babel/plugin-transform-typescript': 7.26.5(@babel/core@7.26.0) - '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.0) - '@vue/compiler-dom': 3.5.13 - kolorist: 1.8.0 - magic-string: 0.30.17 - vite: 6.0.11(@types/node@22.5.5)(jiti@2.4.2)(terser@5.33.0)(yaml@2.7.0) - transitivePeerDependencies: - - supports-color - vite@5.4.10(@types/node@22.5.5)(terser@5.33.0): dependencies: esbuild: 0.21.5 @@ -12565,9 +12077,9 @@ snapshots: terser: 5.33.0 yaml: 2.7.0 - vitest-environment-nuxt@1.0.1(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0): + vitest-environment-nuxt@1.0.1(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0): dependencies: - '@nuxt/test-utils': 3.15.4(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@3.29.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0) + '@nuxt/test-utils': 3.15.4(@types/node@22.5.5)(jiti@2.4.2)(magicast@0.3.5)(rollup@4.24.4)(terser@5.33.0)(typescript@5.6.3)(vitest@3.0.5(@types/node@22.5.5)(terser@5.33.0))(yaml@2.7.0) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -12679,14 +12191,6 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.13(typescript@5.6.3) - vue-tsc@2.1.10(typescript@5.6.3): - dependencies: - '@volar/typescript': 2.4.11 - '@vue/language-core': 2.1.10(typescript@5.6.3) - semver: 7.7.1 - typescript: 5.6.3 - optional: true - vue-tsc@2.2.0(typescript@5.6.3): dependencies: '@volar/typescript': 2.4.11 diff --git a/src/runtime/server/lib/oauth/apple.ts b/src/runtime/server/lib/oauth/apple.ts index d8846fdf..2bd40a62 100644 --- a/src/runtime/server/lib/oauth/apple.ts +++ b/src/runtime/server/lib/oauth/apple.ts @@ -2,7 +2,10 @@ import type { H3Event } from 'h3' import { eventHandler, getRequestHeader, readBody, sendRedirect } from 'h3' import { withQuery } from 'ufo' import { defu } from 'defu' -import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken, signJwt, verifyJwt } from '../utils' +import { importJWKFromPEM } from 'unjwt/jwk' +import type { JWKSet, JWTClaims } from 'unjwt' +import { sign, verify } from 'unjwt/jws' +import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from '../utils' import { useRuntimeConfig } from '#imports' import type { OAuthConfig } from '#auth-utils' @@ -64,9 +67,21 @@ export interface OAuthAppleConfig { * @default process.env.NUXT_OAUTH_APPLE_REDIRECT_URL or current URL */ redirectURL?: string + + /** + * Algorithm to use for signing the JWT. Default is ES256 + * @default 'ES256' + */ + algorithm?: 'RS256' | 'ES256' + + /** + * Expires in seconds + * @default 300 // 5 minutes + */ + expiresIn?: number } -export interface OAuthAppleTokens { +export interface OAuthAppleTokens extends JWTClaims { iss: string aud: string exp: number @@ -138,42 +153,54 @@ export function defineOAuthAppleEventHandler({ // Verify the form post data we got back from apple try { - const secret = await signJwt( + const key = await importJWKFromPEM( + config.privateKey.replace(/\\n/g, '\n'), + 'pkcs8', + config?.algorithm || 'ES256', + ) + + const iat = Math.floor(Date.now() / 1000) + const exp = iat + (config?.expiresIn || 300) // 5 minutes + + const secret = await sign( { + kid: config.keyId, iss: config.teamId, - aud: 'https://appleid.apple.com', sub: config.clientId, + aud: 'https://appleid.apple.com', + iat, + exp, }, - { - privateKey: config.privateKey, - keyId: config.keyId, - teamId: config.teamId, - clientId: config.clientId, - expiresIn: '5m', - }, + key, ) - const accessTokenResult = await requestAccessToken(config.tokenURL || 'https://appleid.apple.com/auth/token', { - params: { - client_id: config.clientId, - client_secret: secret, - code, - grant_type: 'authorization_code', - redirect_uri: config.redirectURL, - }, - }) + const [authroizationGrant, appleKeySet] = await Promise.all([ + requestAccessToken(config.tokenURL || 'https://appleid.apple.com/auth/token', { + params: { + client_id: config.clientId, + client_secret: secret, + code, + grant_type: 'authorization_code', + redirect_uri: config.redirectURL, + }, + }), + $fetch('https://appleid.apple.com/auth/keys'), + ]) - const payload = await verifyJwt(accessTokenResult.id_token, { - publicJwkUrl: 'https://appleid.apple.com/auth/keys', - audience: config.clientId, - issuer: 'https://appleid.apple.com', - }) + const { payload } = await verify( + authroizationGrant.id_token, + appleKeySet, + { + audience: config.clientId, + issuer: 'https://appleid.apple.com', + }, + ) if (!payload) { return handleAccessTokenErrorResponse(event, 'apple', payload, onError) } - return onSuccess(event, { user: user!, payload, tokens: accessTokenResult }) + return onSuccess(event, { user: user!, payload, tokens: authroizationGrant }) } catch (error) { return handleAccessTokenErrorResponse(event, 'apple', error, onError) diff --git a/src/runtime/server/lib/utils.ts b/src/runtime/server/lib/utils.ts index eb631469..ec66cbbb 100644 --- a/src/runtime/server/lib/utils.ts +++ b/src/runtime/server/lib/utils.ts @@ -2,7 +2,6 @@ import { type H3Event, deleteCookie, getCookie, setCookie } from 'h3' import { getRequestURL } from 'h3' import { FetchError } from 'ofetch' import { snakeCase, upperFirst } from 'scule' -import * as jose from 'jose' import { subtle, getRandomValues } from 'uncrypto' import type { OAuthProvider, OnError } from '#auth-utils' import { createError } from '#imports' @@ -50,8 +49,7 @@ export async function requestAccessToken(url: string, options: RequestAccessToke // Encode the body as a URLSearchParams if the content type is 'application/x-www-form-urlencoded'. const body = headers['Content-Type'] === 'application/x-www-form-urlencoded' - ? new URLSearchParams(options.body as unknown as Record || options.params || {}, - ).toString() + ? new URLSearchParams(options.body as unknown as Record || options.params || {}).toString() : options.body return $fetch(url, { @@ -113,63 +111,6 @@ export function handleInvalidState(event: H3Event, provider: OAuthProvider, onEr return onError(event, error) } -/** - * JWT signing using jose - * - * @see https://github.com/panva/jose - */ - -interface JWTSignOptions { - privateKey: string - keyId: string - teamId?: string - clientId?: string - algorithm?: 'ES256' | 'RS256' - expiresIn?: string // e.g., '5m', '1h' -} - -export async function signJwt>( - payload: T, - options: JWTSignOptions, -): Promise { - const now = Math.floor(Date.now() / 1000) - const privateKey = await jose.importPKCS8( - options.privateKey.replace(/\\n/g, '\n'), - options.algorithm || 'ES256', - ) - - return new jose.SignJWT(payload) - .setProtectedHeader({ alg: options.algorithm || 'ES256', kid: options.keyId }) - .setIssuedAt(now) - .setExpirationTime(options.expiresIn || '5m') - .sign(privateKey) -} - -/** - * Verify a JWT token using jose - will throw error if invalid - * - * @see https://github.com/panva/jose - */ -interface JWTVerifyOptions { - publicJwkUrl: string - audience: string - issuer: string -} - -export async function verifyJwt( - token: string, - options: JWTVerifyOptions, -): Promise { - const JWKS = jose.createRemoteJWKSet(new URL(options.publicJwkUrl)) - - const { payload } = await jose.jwtVerify(token, JWKS, { - audience: options.audience, - issuer: options.issuer, - }) - - return payload as T -} - function encodeBase64Url(input: Uint8Array): string { return btoa(String.fromCharCode.apply(null, input as unknown as number[])) .replace(/\+/g, '-')