@devcoffee/nuxt-core 1.2.4 → 1.3.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 +29 -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.js +3 -3
- 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 +2 -2
- package/dist/runtime/server/plugins/authts.js +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.3.0
|
|
4
|
+
|
|
5
|
+
[compare changes](https://github.com/coolkg1412/devcoffee-nuxt-core/compare/v1.2.5...v1.3.0)
|
|
6
|
+
|
|
7
|
+
### 🚀 Enhancements
|
|
8
|
+
|
|
9
|
+
- Enhance locale and timezone handling with session support in formatters plugin ([c36f621](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/c36f621))
|
|
10
|
+
|
|
11
|
+
### 🩹 Fixes
|
|
12
|
+
|
|
13
|
+
- Harden useAuthContext composable and logging infrastructure ([2a89ebf](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/2a89ebf))
|
|
14
|
+
- Correct sessionCookieId reference in validateSession call in authts.ts tests ([2c8b343](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/2c8b343))
|
|
15
|
+
|
|
16
|
+
### ❤️ Contributors
|
|
17
|
+
|
|
18
|
+
- Hieu Nguyen <hieu.nguyen@devcoffee.tech>
|
|
19
|
+
|
|
20
|
+
## v1.2.5
|
|
21
|
+
|
|
22
|
+
[compare changes](https://github.com/coolkg1412/devcoffee-nuxt-core/compare/v1.2.4...v1.2.5)
|
|
23
|
+
|
|
24
|
+
### 🩹 Fixes
|
|
25
|
+
|
|
26
|
+
- Update sourcemap configuration to reflect NODE_ENV for server and client ([4ded743](https://github.com/coolkg1412/devcoffee-nuxt-core/commit/4ded743))
|
|
27
|
+
|
|
28
|
+
### ❤️ Contributors
|
|
29
|
+
|
|
30
|
+
- Hieu Nguyen <hieu.nguyen@devcoffee.tech>
|
|
31
|
+
|
|
3
32
|
## v1.2.4
|
|
4
33
|
|
|
5
34
|
[compare changes](https://github.com/coolkg1412/devcoffee-nuxt-core/compare/v1.2.3...v1.2.4)
|
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.3.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
|
}
|
|
@@ -66,7 +66,7 @@ export async function getSession(sessionId, opts) {
|
|
|
66
66
|
const decrypted = decryptTokenSet(session.auth.tokenSet, opts.secret);
|
|
67
67
|
session.auth.tokenSet = decrypted ?? void 0;
|
|
68
68
|
} else {
|
|
69
|
-
const logger = useServerLogger({ tag: "authts-helper"
|
|
69
|
+
const logger = useServerLogger({ tag: "authts-helper" });
|
|
70
70
|
logger.warn(
|
|
71
71
|
"[getSession] tokenSet is encrypted but sessions.secret is not configured \u2014 tokenSet will be inaccessible"
|
|
72
72
|
);
|
|
@@ -172,7 +172,7 @@ export async function deleteSession(sessionId, opts) {
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
export async function discoveryOpendId(wellKnownUrl, opts) {
|
|
175
|
-
const logger = useServerLogger({ tag: "authts-helper"
|
|
175
|
+
const logger = useServerLogger({ tag: "authts-helper" });
|
|
176
176
|
const {
|
|
177
177
|
cache: { prefix: cachedPrefix, expires },
|
|
178
178
|
clientId,
|
|
@@ -304,7 +304,7 @@ export function constructTokenSet(input) {
|
|
|
304
304
|
};
|
|
305
305
|
}
|
|
306
306
|
export async function refreshTokenIfNeeded(session, opts) {
|
|
307
|
-
const logger = useServerLogger({ tag: "authts-helper"
|
|
307
|
+
const logger = useServerLogger({ tag: "authts-helper" });
|
|
308
308
|
let updateSession2 = {
|
|
309
309
|
auth: { status: "unauthenticated", tokenSet: void 0 },
|
|
310
310
|
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
|
}
|
|
@@ -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({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineNitroPlugin, getCookie, setCookie, useRuntimeConfig } from "#devcoffee-core/server/adapters/http";
|
|
2
|
+
import useServerLogger from "#devcoffee-core/server/composables/useServerLogger";
|
|
2
3
|
import { signSessionId } from "#devcoffee-core/server/core/crypto";
|
|
3
4
|
import { refreshTokenIfNeeded, updateSession, validateSession } from "#devcoffee-core/server/core/helpers";
|
|
4
5
|
import { useNitroApp, useStorage } from "nitropack/runtime";
|
|
@@ -23,7 +24,9 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
23
24
|
names: { sessionId: cookieName }
|
|
24
25
|
}
|
|
25
26
|
} = useRuntimeConfig(event).nuxtCore.authts;
|
|
26
|
-
|
|
27
|
+
const sessionCookieId = getCookie(event, cookieName);
|
|
28
|
+
const logger = useServerLogger({ event, tag: "plugin.auth" });
|
|
29
|
+
let session = await validateSession(sessionCookieId, {
|
|
27
30
|
storageName,
|
|
28
31
|
storagePrefix,
|
|
29
32
|
expiresIn,
|
|
@@ -47,6 +50,7 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
47
50
|
const userInfoCacheKey = `${cache.prefix}:userinfo:${session.id}`;
|
|
48
51
|
let cachedUser = await cacheStorage.getItem(userInfoCacheKey);
|
|
49
52
|
if (!cachedUser) {
|
|
53
|
+
logger.debug("refetch user info sessionid=%s", sessionCookieId);
|
|
50
54
|
const userInfoFn = useNitroApp()._sessionUserInfo;
|
|
51
55
|
if (userInfoFn && session.auth.tokenSet) {
|
|
52
56
|
cachedUser = await userInfoFn(session.user, { tokenSet: session.auth.tokenSet });
|