@devcoffee/nuxt-core 1.2.5 → 1.4.0
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/CHANGELOG.md +39 -0
- package/dist/module.d.mts +4 -1
- package/dist/module.d.ts +4 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -2
- package/dist/runtime/app/composables/useAuthContext.d.ts +7 -4
- package/dist/runtime/app/composables/useAuthContext.js +1 -1
- package/dist/runtime/app/middleware/authts.js +1 -1
- package/dist/runtime/app/plugins/formatters.js +15 -6
- package/dist/runtime/app/plugins/locale.js +1 -1
- package/dist/runtime/app/plugins/logging.js +7 -4
- package/dist/runtime/server/composables/useServerLogger.d.ts +1 -1
- package/dist/runtime/server/composables/useServerLogger.js +15 -6
- package/dist/runtime/server/core/helpers.d.ts +23 -0
- package/dist/runtime/server/core/helpers.js +24 -5
- package/dist/runtime/server/core/mutex.js +1 -1
- package/dist/runtime/server/core/nuxtAuthtsHandler.js +3 -0
- package/dist/runtime/server/core/nuxtForwardHandler.js +13 -4
- package/dist/runtime/server/plugins/authts.js +14 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.4.0
|
|
4
|
+
|
|
5
|
+
[compare changes](https://github.com/coolkg1412/devcoffee-nuxt-core/compare/v1.3.0...v1.4.0)
|
|
6
|
+
|
|
7
|
+
### 🚀 Enhancements
|
|
8
|
+
|
|
9
|
+
- Implement writeSessionCookie function and integrate it into NuxtForwardRequestHandler and authts plugin ([e761f6c](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/e761f6c))
|
|
10
|
+
|
|
11
|
+
### 🩹 Fixes
|
|
12
|
+
|
|
13
|
+
- Drop return from proxyRequest in NuxtForwardRequestHandler to prevent ERR_HTTP_HEADERS_SENT ([fd3b91c](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/fd3b91c))
|
|
14
|
+
- Prevent sending headers after response has been finalized in beforeResponse hook ([444a012](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/444a012))
|
|
15
|
+
- Update version to 1.3.2 in package.json and package-lock.json ([e6ab449](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/e6ab449))
|
|
16
|
+
|
|
17
|
+
### 💅 Refactors
|
|
18
|
+
|
|
19
|
+
- Remove redundant signSessionId checks from authts.sec03.test.ts ([18686f4](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/18686f4))
|
|
20
|
+
|
|
21
|
+
### ❤️ Contributors
|
|
22
|
+
|
|
23
|
+
- Hieu Nguyen <hieu.nguyen@devcoffee.tech>
|
|
24
|
+
|
|
25
|
+
## v1.3.0
|
|
26
|
+
|
|
27
|
+
[compare changes](https://github.com/coolkg1412/devcoffee-nuxt-core/compare/v1.2.5...v1.3.0)
|
|
28
|
+
|
|
29
|
+
### 🚀 Enhancements
|
|
30
|
+
|
|
31
|
+
- Enhance locale and timezone handling with session support in formatters plugin ([c36f621](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/c36f621))
|
|
32
|
+
|
|
33
|
+
### 🩹 Fixes
|
|
34
|
+
|
|
35
|
+
- Harden useAuthContext composable and logging infrastructure ([2a89ebf](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/2a89ebf))
|
|
36
|
+
- Correct sessionCookieId reference in validateSession call in authts.ts tests ([2c8b343](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/2c8b343))
|
|
37
|
+
|
|
38
|
+
### ❤️ Contributors
|
|
39
|
+
|
|
40
|
+
- Hieu Nguyen <hieu.nguyen@devcoffee.tech>
|
|
41
|
+
|
|
3
42
|
## v1.2.5
|
|
4
43
|
|
|
5
44
|
[compare changes](https://github.com/coolkg1412/devcoffee-nuxt-core/compare/v1.2.4...v1.2.5)
|
package/dist/module.d.mts
CHANGED
|
@@ -264,6 +264,9 @@ type LoggingModuleOptions = {
|
|
|
264
264
|
server: LoggingOptions
|
|
265
265
|
ssr: LoggingOptions
|
|
266
266
|
client: LoggingOptions
|
|
267
|
+
loggers?: {
|
|
268
|
+
[key: string]: Omit<LoggingOptions, 'tag'>
|
|
269
|
+
}
|
|
267
270
|
}
|
|
268
271
|
|
|
269
272
|
type ModuleOptions = {
|
|
@@ -276,7 +279,7 @@ type ModuleOptions = {
|
|
|
276
279
|
}
|
|
277
280
|
|
|
278
281
|
type ModulePublicRuntimeConfig = Pick<ModuleOptions, 'defaultLocale' | 'defaultTimeZone' | 'defaultLanguage'> & {
|
|
279
|
-
logging: ModuleOptions['logging']['client']
|
|
282
|
+
logging: ModuleOptions['logging']['client'] & { loggers: ModuleOptions['logging']['loggers'] }
|
|
280
283
|
|
|
281
284
|
authts: Pick<
|
|
282
285
|
AuthtsModuleOptions['auth'],
|
package/dist/module.d.ts
CHANGED
|
@@ -264,6 +264,9 @@ type LoggingModuleOptions = {
|
|
|
264
264
|
server: LoggingOptions
|
|
265
265
|
ssr: LoggingOptions
|
|
266
266
|
client: LoggingOptions
|
|
267
|
+
loggers?: {
|
|
268
|
+
[key: string]: Omit<LoggingOptions, 'tag'>
|
|
269
|
+
}
|
|
267
270
|
}
|
|
268
271
|
|
|
269
272
|
type ModuleOptions = {
|
|
@@ -276,7 +279,7 @@ type ModuleOptions = {
|
|
|
276
279
|
}
|
|
277
280
|
|
|
278
281
|
type ModulePublicRuntimeConfig = Pick<ModuleOptions, 'defaultLocale' | 'defaultTimeZone' | 'defaultLanguage'> & {
|
|
279
|
-
logging: ModuleOptions['logging']['client']
|
|
282
|
+
logging: ModuleOptions['logging']['client'] & { loggers: ModuleOptions['logging']['loggers'] }
|
|
280
283
|
|
|
281
284
|
authts: Pick<
|
|
282
285
|
AuthtsModuleOptions['auth'],
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { addCustomTab } from '@nuxt/devtools-kit';
|
|
|
2
2
|
import { defineNuxtModule, useLogger, createResolver, addTemplate, addServerImports, addServerImportsDir, addServerPlugin, addImportsDir, addPlugin, addRouteMiddleware, addServerHandler } from '@nuxt/kit';
|
|
3
3
|
import { deepMerge, pick } from '../dist/runtime/utils.js';
|
|
4
4
|
|
|
5
|
-
const version = "1.
|
|
5
|
+
const version = "1.4.0";
|
|
6
6
|
|
|
7
7
|
const defaultLocale = "vi-VN";
|
|
8
8
|
const defaultLanguage = "vi";
|
|
@@ -95,7 +95,7 @@ function normalizePublicRuntimeConfig(inputOpts) {
|
|
|
95
95
|
const { redirectUri } = inputOpts.authts.openid;
|
|
96
96
|
const { redirectUrl: redirectCookie, sessionId: sessionCookie } = inputOpts.authts.sessions.names;
|
|
97
97
|
return {
|
|
98
|
-
logging: { ...inputOpts.logging.client },
|
|
98
|
+
logging: { ...inputOpts.logging.client, loggers: inputOpts.logging.loggers },
|
|
99
99
|
authts: {
|
|
100
100
|
enabled,
|
|
101
101
|
loginUri,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { AuthorizedUser } from '@devcoffee/nuxt-core';
|
|
2
|
+
import { type NuxtSessionContext } from '#app';
|
|
3
|
+
import { type ComputedRef, type Ref } from '#imports';
|
|
1
4
|
/**
|
|
2
5
|
* 🧩 Provides reactive authentication state and actions for user login and authorization.
|
|
3
6
|
*
|
|
@@ -16,10 +19,10 @@
|
|
|
16
19
|
* @since 1.0.0
|
|
17
20
|
*/
|
|
18
21
|
export declare function useAuthContext(initiator?: string): {
|
|
19
|
-
user:
|
|
20
|
-
session:
|
|
21
|
-
processing:
|
|
22
|
-
isAuthenticated:
|
|
22
|
+
user: ComputedRef<AuthorizedUser>;
|
|
23
|
+
session: ComputedRef<NuxtSessionContext>;
|
|
24
|
+
processing: Ref<boolean>;
|
|
25
|
+
isAuthenticated: ComputedRef<boolean>;
|
|
23
26
|
login: (redirectTo?: string) => Promise<void>;
|
|
24
27
|
authorize: (parameters: URLSearchParams) => Promise<void>;
|
|
25
28
|
logout: () => Promise<void>;
|
|
@@ -14,7 +14,7 @@ export function useAuthContext(initiator) {
|
|
|
14
14
|
const { callHook, runWithContext } = useNuxtApp();
|
|
15
15
|
const { getValue } = useSessionContext();
|
|
16
16
|
const fetchRequest = useRequestFetch();
|
|
17
|
-
const logger = useLogger({
|
|
17
|
+
const logger = useLogger({ tag: "auth.context" });
|
|
18
18
|
const processing = ref(false);
|
|
19
19
|
const session = computed(() => getValue(initiator, "useAuthContext.session"));
|
|
20
20
|
const isAuthenticated = computed(() => {
|
|
@@ -52,7 +52,7 @@ function getRedirectCookie(name) {
|
|
|
52
52
|
export default defineNuxtRouteMiddleware(async (to) => {
|
|
53
53
|
const nuxtApp = useNuxtApp();
|
|
54
54
|
await nuxtApp.$sessionReady;
|
|
55
|
-
const logger = useLogger({ tag: "authts.middleware"
|
|
55
|
+
const logger = useLogger({ tag: "authts.middleware" });
|
|
56
56
|
const {
|
|
57
57
|
loginUri,
|
|
58
58
|
defaultLoginRedirectUri,
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
|
-
import {
|
|
1
|
+
import { defineNuxtPlugin, useRequestEvent, useRuntimeConfig, useState } from "#app";
|
|
2
|
+
import { useLogger } from "#imports";
|
|
3
3
|
export default defineNuxtPlugin((_nuxtApp) => {
|
|
4
|
-
const logger = useLogger({ tag: "formatters"
|
|
4
|
+
const logger = useLogger({ tag: "formatters" });
|
|
5
5
|
const { defaultLocale, defaultLanguage, defaultTimeZone } = useRuntimeConfig().public.nuxtCore;
|
|
6
|
-
const currentLocale =
|
|
7
|
-
const currentLanguage =
|
|
8
|
-
const currentTimeZone =
|
|
6
|
+
const currentLocale = useState("devcoffee.formatters.locale", () => defaultLocale);
|
|
7
|
+
const currentLanguage = useState("devcoffee.formatters.language", () => defaultLanguage);
|
|
8
|
+
const currentTimeZone = useState("devcoffee.formatters.timeZone", () => defaultTimeZone);
|
|
9
|
+
if (import.meta.server) {
|
|
10
|
+
const event = useRequestEvent();
|
|
11
|
+
const session = event?.context?.session ?? null;
|
|
12
|
+
if (session?.user) {
|
|
13
|
+
if (session.user.locale) currentLocale.value = session.user.locale;
|
|
14
|
+
if (session.user.language) currentLanguage.value = session.user.language;
|
|
15
|
+
if (session.user.timezone) currentTimeZone.value = session.user.timezone;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
9
18
|
_nuxtApp.hooks.addHooks({
|
|
10
19
|
"dfLocale:changed": (value) => {
|
|
11
20
|
const { locale = defaultLocale, timeZone = defaultTimeZone, language = defaultLanguage } = value;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRuntimeConfig, useState } from "#app";
|
|
2
2
|
import { useAuthContext, useLogger, watch } from "#imports";
|
|
3
3
|
export default defineNuxtPlugin(async (_nuxtApp) => {
|
|
4
|
-
const logger = useLogger({ tag: "plugin.locale"
|
|
4
|
+
const logger = useLogger({ tag: "plugin.locale" });
|
|
5
5
|
const { defaultLocale, defaultLanguage, defaultTimeZone } = useRuntimeConfig().public.nuxtCore;
|
|
6
6
|
const localeState = useState("devecoffee.locale", () => ({
|
|
7
7
|
locale: defaultLocale,
|
|
@@ -13,13 +13,16 @@ function initLogger() {
|
|
|
13
13
|
}
|
|
14
14
|
export default defineNuxtPlugin(async (_nuxtApp) => {
|
|
15
15
|
const logger = reactive(initLogger());
|
|
16
|
+
const loggers = useRuntimeConfig().public.nuxtCore.logging.loggers;
|
|
16
17
|
function getLogger(opts) {
|
|
17
|
-
|
|
18
|
+
opts = opts || {};
|
|
18
19
|
let _logger = logger;
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const _opts = opts.tag && loggers && loggers[opts.tag] ? loggers[opts.tag] : { level: logger.level };
|
|
21
|
+
if (opts.level) {
|
|
22
|
+
_opts.level = opts.level;
|
|
21
23
|
}
|
|
22
|
-
|
|
24
|
+
_logger = _logger.create(_opts);
|
|
25
|
+
return opts.tag != void 0 ? _logger.withTag(opts.tag) : _logger;
|
|
23
26
|
}
|
|
24
27
|
return { provide: { logging: { getLogger } } };
|
|
25
28
|
});
|
|
@@ -2,14 +2,23 @@ import { consola } from "consola";
|
|
|
2
2
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
3
3
|
let globalServerLogger;
|
|
4
4
|
export default function useServerLogger(options) {
|
|
5
|
-
|
|
5
|
+
options = options || {};
|
|
6
|
+
const { server, loggers = {} } = useRuntimeConfig(options?.event).nuxtCore.logging;
|
|
7
|
+
const { tag: rootTag, ...opts } = server;
|
|
6
8
|
if (!globalServerLogger) {
|
|
7
|
-
globalServerLogger = consola.create(opts).withTag(
|
|
9
|
+
globalServerLogger = consola.create(opts).withTag(rootTag);
|
|
8
10
|
}
|
|
9
11
|
let _logger = globalServerLogger;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
_logger = _logger.create({ level });
|
|
12
|
+
if (!options.tag && options.level != opts.level) {
|
|
13
|
+
return _logger;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
let _opt = { level: opts.level };
|
|
16
|
+
if (options.tag && options.tag in loggers) {
|
|
17
|
+
_opt = loggers[options.tag];
|
|
18
|
+
}
|
|
19
|
+
if (options.level) {
|
|
20
|
+
_opt.level = options.level;
|
|
21
|
+
}
|
|
22
|
+
_logger = _logger.create(_opt);
|
|
23
|
+
return options.tag != void 0 ? _logger.withTag(options.tag) : _logger;
|
|
15
24
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionContext } from '@devcoffee/nuxt-core';
|
|
2
|
+
import type { CookieSerializeOptions, H3Event } from '#devcoffee-core/server/adapters/http';
|
|
2
3
|
import type { ClientMetadata, ServerMetadata, TokenEndpointResponse } from '#devcoffee-core/server/adapters/oidc';
|
|
3
4
|
/** Options used for session creation and validation. */
|
|
4
5
|
type SessionCreateOptions = {
|
|
@@ -19,6 +20,28 @@ type SessionCreateOptions = {
|
|
|
19
20
|
* @since 1.0.0
|
|
20
21
|
*/
|
|
21
22
|
export declare function isSameOrigin(redirectUrl: string, requestUrl: URL): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Write the session cookie to the response.
|
|
25
|
+
*
|
|
26
|
+
* Shared by the `beforeResponse` Nitro hook (buffered responses) and the
|
|
27
|
+
* `proxyRequest` `onResponse` callback (streaming proxy responses). Calling
|
|
28
|
+
* it in both places ensures the cookie is always refreshed regardless of
|
|
29
|
+
* whether `headersSent` is true by the time `beforeResponse` fires.
|
|
30
|
+
*
|
|
31
|
+
* @param event - The H3 event for the current request.
|
|
32
|
+
* @param session - The resolved session context to encode into the cookie.
|
|
33
|
+
* @param sessionsConfig - Session cookie options from `nuxtCore.authts.sessions`.
|
|
34
|
+
* @since 1.3.3
|
|
35
|
+
*/
|
|
36
|
+
export declare function writeSessionCookie(event: H3Event, session: SessionContext, sessionsConfig: {
|
|
37
|
+
cookieOpts: Omit<CookieSerializeOptions, 'sameSite'> & {
|
|
38
|
+
sameSite?: string | boolean;
|
|
39
|
+
};
|
|
40
|
+
secret?: string;
|
|
41
|
+
names: {
|
|
42
|
+
sessionId: string;
|
|
43
|
+
};
|
|
44
|
+
}): void;
|
|
22
45
|
/**
|
|
23
46
|
* Retrieve an existing session from storage.
|
|
24
47
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createError } from "#devcoffee-core/server/adapters/http";
|
|
1
|
+
import { createError, setCookie } from "#devcoffee-core/server/adapters/http";
|
|
2
2
|
import {
|
|
3
3
|
allowInsecureRequests,
|
|
4
4
|
authorizationCodeGrant as authorizationCodeGrantOidc,
|
|
@@ -22,7 +22,14 @@ import { deepMerge, omit } from "#devcoffee-core/server/adapters/utils";
|
|
|
22
22
|
import useServerLogger from "#devcoffee-core/server/composables/useServerLogger";
|
|
23
23
|
import { useRuntimeConfig } from "#imports";
|
|
24
24
|
import { useStorage } from "nitropack/runtime";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
decryptTokenSet,
|
|
27
|
+
encryptTokenSet,
|
|
28
|
+
generateSessionId,
|
|
29
|
+
isValidSessionId,
|
|
30
|
+
signSessionId,
|
|
31
|
+
verifySessionId
|
|
32
|
+
} from "./crypto.js";
|
|
26
33
|
import { tryAcquireLock } from "./mutex.js";
|
|
27
34
|
function getAnonymousUser(extras) {
|
|
28
35
|
const anonymous = useRuntimeConfig().nuxtCore.authts.auth.anonymousUser;
|
|
@@ -56,6 +63,18 @@ export function isSameOrigin(redirectUrl, requestUrl) {
|
|
|
56
63
|
return false;
|
|
57
64
|
}
|
|
58
65
|
}
|
|
66
|
+
export function writeSessionCookie(event, session, sessionsConfig) {
|
|
67
|
+
const {
|
|
68
|
+
cookieOpts,
|
|
69
|
+
secret = "",
|
|
70
|
+
names: { sessionId: cookieName }
|
|
71
|
+
} = sessionsConfig;
|
|
72
|
+
const cookieValue = secret ? signSessionId(session.id, secret) : session.id;
|
|
73
|
+
setCookie(event, cookieName, cookieValue, {
|
|
74
|
+
...cookieOpts,
|
|
75
|
+
expires: new Date(session.expiresAt)
|
|
76
|
+
});
|
|
77
|
+
}
|
|
59
78
|
export async function getSession(sessionId, opts) {
|
|
60
79
|
const sessingKey = getSessionStorageKey(opts.storagePrefix, sessionId);
|
|
61
80
|
if (!await hasSessionData(opts.storageName, sessingKey)) return null;
|
|
@@ -66,7 +85,7 @@ export async function getSession(sessionId, opts) {
|
|
|
66
85
|
const decrypted = decryptTokenSet(session.auth.tokenSet, opts.secret);
|
|
67
86
|
session.auth.tokenSet = decrypted ?? void 0;
|
|
68
87
|
} else {
|
|
69
|
-
const logger = useServerLogger({ tag: "authts-helper"
|
|
88
|
+
const logger = useServerLogger({ tag: "authts-helper" });
|
|
70
89
|
logger.warn(
|
|
71
90
|
"[getSession] tokenSet is encrypted but sessions.secret is not configured \u2014 tokenSet will be inaccessible"
|
|
72
91
|
);
|
|
@@ -172,7 +191,7 @@ export async function deleteSession(sessionId, opts) {
|
|
|
172
191
|
}
|
|
173
192
|
}
|
|
174
193
|
export async function discoveryOpendId(wellKnownUrl, opts) {
|
|
175
|
-
const logger = useServerLogger({ tag: "authts-helper"
|
|
194
|
+
const logger = useServerLogger({ tag: "authts-helper" });
|
|
176
195
|
const {
|
|
177
196
|
cache: { prefix: cachedPrefix, expires },
|
|
178
197
|
clientId,
|
|
@@ -304,7 +323,7 @@ export function constructTokenSet(input) {
|
|
|
304
323
|
};
|
|
305
324
|
}
|
|
306
325
|
export async function refreshTokenIfNeeded(session, opts) {
|
|
307
|
-
const logger = useServerLogger({ tag: "authts-helper"
|
|
326
|
+
const logger = useServerLogger({ tag: "authts-helper" });
|
|
308
327
|
let updateSession2 = {
|
|
309
328
|
auth: { status: "unauthenticated", tokenSet: void 0 },
|
|
310
329
|
user: getAnonymousUser()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import useServerLogger from "#devcoffee-core/server/composables/useServerLogger";
|
|
2
2
|
import { useStorage } from "nitropack/runtime";
|
|
3
|
-
const logger = useServerLogger({ tag: "authts-mutex", level: 3 });
|
|
4
3
|
export async function tryAcquireLock(storage, lockKey, ttlSeconds, useAtomic) {
|
|
4
|
+
const logger = useServerLogger({ tag: "authts-mutex" });
|
|
5
5
|
if (useAtomic) {
|
|
6
6
|
try {
|
|
7
7
|
const baseStorage = useStorage();
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
useRuntimeConfig
|
|
11
11
|
} from "#devcoffee-core/server/adapters/http";
|
|
12
12
|
import { deepMerge, omit } from "#devcoffee-core/server/adapters/utils";
|
|
13
|
+
import useServerLogger from "#devcoffee-core/server/composables/useServerLogger";
|
|
13
14
|
import { useNitroApp, useStorage } from "nitropack/runtime";
|
|
14
15
|
import {
|
|
15
16
|
authorizationCodeGrant,
|
|
@@ -71,6 +72,7 @@ export default function NuxtAuthtsHandler(options) {
|
|
|
71
72
|
const requestUrl = getRequestURL(event);
|
|
72
73
|
const queryParams = getQuery(event);
|
|
73
74
|
const authAction = getAuthAction(requestUrl);
|
|
75
|
+
const logger = useServerLogger({ event, tag: "auth.handler" });
|
|
74
76
|
let session = event.context.session;
|
|
75
77
|
if (!session) {
|
|
76
78
|
throw createError({
|
|
@@ -97,6 +99,7 @@ export default function NuxtAuthtsHandler(options) {
|
|
|
97
99
|
const userInfoCacheKey = `${openid.cache.prefix}:userinfo:${session.id}`;
|
|
98
100
|
let cachedUser = await cacheStorage2.getItem(userInfoCacheKey);
|
|
99
101
|
if (!cachedUser) {
|
|
102
|
+
logger.debug("Re-fetch user info");
|
|
100
103
|
cachedUser = await nuxtAuthOptions.userInfo(session.user, { tokenSet: session.auth.tokenSet });
|
|
101
104
|
await cacheStorage2.setItem(userInfoCacheKey, cachedUser, { ttl: openid.autoFetchUserTtl });
|
|
102
105
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "#devcoffee-core/server/adapters/http";
|
|
8
8
|
import { deepMerge } from "#devcoffee-core/server/adapters/utils";
|
|
9
9
|
import useServerLogger from "#devcoffee-core/server/composables/useServerLogger";
|
|
10
|
-
import { getOpenIdConfiguration } from "./helpers.js";
|
|
10
|
+
import { getOpenIdConfiguration, writeSessionCookie } from "./helpers.js";
|
|
11
11
|
const defaultOpts = {
|
|
12
12
|
logLevel: 2,
|
|
13
13
|
proxyPrefix: ""
|
|
@@ -22,8 +22,8 @@ function resolveOptions(opts) {
|
|
|
22
22
|
return deepMerge({ ...defaultOpts }, resolvedOpts || {});
|
|
23
23
|
}
|
|
24
24
|
export default function NuxtForwardRequestHandler(opts) {
|
|
25
|
-
const {
|
|
26
|
-
const logger = useServerLogger({ tag: "forward-request"
|
|
25
|
+
const { targetBaseUrl, proxyPrefix, onBeforeRequest } = resolveOptions(opts);
|
|
26
|
+
const logger = useServerLogger({ tag: "forward-request" });
|
|
27
27
|
if (!targetBaseUrl) {
|
|
28
28
|
logger.error("no targetBaseUrl");
|
|
29
29
|
throw createError({
|
|
@@ -51,6 +51,15 @@ export default function NuxtForwardRequestHandler(opts) {
|
|
|
51
51
|
};
|
|
52
52
|
logger.info(`from '${event.path}' to '${defaultForwardInit.forwardUrl}' - auth stt='${session?.auth?.status}'`);
|
|
53
53
|
const { forwardUrl, ...proxyOption } = await onBeforeRequest?.(defaultForwardInit, params) || defaultForwardInit;
|
|
54
|
-
|
|
54
|
+
const { sessions } = useRuntimeConfig(event).nuxtCore.authts;
|
|
55
|
+
await proxyRequest(event, forwardUrl, {
|
|
56
|
+
...proxyOption,
|
|
57
|
+
onResponse(proxyEvent, _upstreamResponse) {
|
|
58
|
+
const session2 = proxyEvent.context.session;
|
|
59
|
+
if (session2) {
|
|
60
|
+
writeSessionCookie(proxyEvent, session2, sessions);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
55
64
|
});
|
|
56
65
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { defineNitroPlugin, getCookie,
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { defineNitroPlugin, getCookie, useRuntimeConfig } from "#devcoffee-core/server/adapters/http";
|
|
2
|
+
import useServerLogger from "#devcoffee-core/server/composables/useServerLogger";
|
|
3
|
+
import {
|
|
4
|
+
refreshTokenIfNeeded,
|
|
5
|
+
updateSession,
|
|
6
|
+
validateSession,
|
|
7
|
+
writeSessionCookie
|
|
8
|
+
} from "#devcoffee-core/server/core/helpers";
|
|
4
9
|
import { useNitroApp, useStorage } from "nitropack/runtime";
|
|
5
10
|
export default defineNitroPlugin((nitroApp) => {
|
|
6
11
|
nitroApp.hooks.hook("request", async (event) => {
|
|
@@ -23,7 +28,9 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
23
28
|
names: { sessionId: cookieName }
|
|
24
29
|
}
|
|
25
30
|
} = useRuntimeConfig(event).nuxtCore.authts;
|
|
26
|
-
|
|
31
|
+
const sessionCookieId = getCookie(event, cookieName);
|
|
32
|
+
const logger = useServerLogger({ event, tag: "plugin.auth" });
|
|
33
|
+
let session = await validateSession(sessionCookieId, {
|
|
27
34
|
storageName,
|
|
28
35
|
storagePrefix,
|
|
29
36
|
expiresIn,
|
|
@@ -47,6 +54,7 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
47
54
|
const userInfoCacheKey = `${cache.prefix}:userinfo:${session.id}`;
|
|
48
55
|
let cachedUser = await cacheStorage.getItem(userInfoCacheKey);
|
|
49
56
|
if (!cachedUser) {
|
|
57
|
+
logger.debug("refetch user info sessionid=%s", sessionCookieId);
|
|
50
58
|
const userInfoFn = useNitroApp()._sessionUserInfo;
|
|
51
59
|
if (userInfoFn && session.auth.tokenSet) {
|
|
52
60
|
cachedUser = await userInfoFn(session.user, { tokenSet: session.auth.tokenSet });
|
|
@@ -61,18 +69,10 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
61
69
|
event.context.session = session;
|
|
62
70
|
});
|
|
63
71
|
nitroApp.hooks.hook("beforeResponse", async (event) => {
|
|
64
|
-
|
|
65
|
-
cookieOpts,
|
|
66
|
-
secret = "",
|
|
67
|
-
names: { sessionId: cookieName }
|
|
68
|
-
} = useRuntimeConfig(event).nuxtCore.authts.sessions;
|
|
72
|
+
if (event.node.res.headersSent) return;
|
|
69
73
|
const session = event.context.session;
|
|
70
74
|
if (session) {
|
|
71
|
-
|
|
72
|
-
setCookie(event, cookieName, cookieValue, {
|
|
73
|
-
...cookieOpts,
|
|
74
|
-
expires: new Date(session.expiresAt)
|
|
75
|
-
});
|
|
75
|
+
writeSessionCookie(event, session, useRuntimeConfig(event).nuxtCore.authts.sessions);
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
78
|
});
|