@meistrari/auth-nuxt 2.2.2 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meistrari/auth-nuxt",
3
3
  "configKey": "telaAuth",
4
- "version": "2.2.2",
4
+ "version": "2.3.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -66,6 +66,11 @@ const module$1 = defineNuxtModule({
66
66
  handler: resolver.resolve("./runtime/server/routes/auth/switch-organization"),
67
67
  method: "post"
68
68
  });
69
+ addServerHandler({
70
+ route: "/auth/whoami",
71
+ handler: resolver.resolve("./runtime/server/routes/auth/whoami"),
72
+ method: "get"
73
+ });
69
74
  addPlugin(resolver.resolve("./runtime/plugins/application-token-refresh"));
70
75
  addPlugin(resolver.resolve("./runtime/plugins/auth-guard"));
71
76
  addPlugin(resolver.resolve("./runtime/plugins/directives"));
@@ -1,11 +1,4 @@
1
- type RawOrganization = {
2
- title: string;
3
- id: string;
4
- createdAt: Date;
5
- avatarUrl: string | null;
6
- metadata: string | null;
7
- slug: string | null;
8
- };
1
+ import type { FullOrganization } from '@meistrari/auth-core';
9
2
  /**
10
3
  * Composable for managing Tela application authentication with OAuth 2.0 PKCE flow
11
4
  *
@@ -44,7 +37,7 @@ export declare function useTelaApplicationAuth(): {
44
37
  login: () => Promise<void>;
45
38
  logout: () => Promise<void>;
46
39
  initSession: () => Promise<void>;
47
- getAvailableOrganizations: () => Promise<RawOrganization[]>;
40
+ getAvailableOrganizations: () => Promise<FullOrganization[]>;
48
41
  switchOrganization: (organizationId: string) => Promise<void>;
49
42
  refreshToken: () => Promise<void>;
50
43
  user: import("vue").Ref<{
@@ -76,6 +69,5 @@ export declare function useTelaApplicationAuth(): {
76
69
  banExpires?: Date | null | undefined;
77
70
  lastActiveAt?: Date | null | undefined;
78
71
  } | null>;
79
- activeOrganization: import("vue").Ref<Omit<import("@meistrari/auth-core").FullOrganization, "members" | "invitations" | "teams"> | null, Omit<import("@meistrari/auth-core").FullOrganization, "members" | "invitations" | "teams"> | null>;
72
+ activeOrganization: import("vue").Ref<FullOrganization | null, FullOrganization | null>;
80
73
  };
81
- export {};
@@ -3,16 +3,6 @@ import { AuthorizationFlowError, isTokenExpired, RefreshTokenExpiredError, UserN
3
3
  import { useApplicationSessionState } from "./state.js";
4
4
  const FIFTEEN_MINUTES = 60 * 15;
5
5
  const ONE_MINUTE = 60 * 1e3;
6
- function mapOrganization(organization) {
7
- return {
8
- name: organization.title,
9
- id: organization.id,
10
- createdAt: organization.createdAt,
11
- logo: organization.avatarUrl,
12
- metadata: organization.metadata,
13
- slug: organization.slug ?? ""
14
- };
15
- }
16
6
  export function useTelaApplicationAuth() {
17
7
  const appConfig = useRuntimeConfig().public.telaAuth;
18
8
  const accessTokenCookie = useCookie("tela-access-token", {
@@ -60,7 +50,7 @@ export function useTelaApplicationAuth() {
60
50
  method: "POST"
61
51
  });
62
52
  state.user.value = result.user;
63
- state.activeOrganization.value = mapOrganization(result.organization);
53
+ state.activeOrganization.value = result.organization;
64
54
  } catch (error) {
65
55
  console.error("[Auth Refresh] Failed to refresh token:", error);
66
56
  throw new RefreshTokenExpiredError();
@@ -91,7 +81,7 @@ export function useTelaApplicationAuth() {
91
81
  body: { organizationId }
92
82
  });
93
83
  state.user.value = result.user;
94
- state.activeOrganization.value = mapOrganization(result.organization);
84
+ state.activeOrganization.value = result.organization;
95
85
  } catch (error) {
96
86
  console.error("[Auth Switch Org] Failed to switch organization:", error);
97
87
  throw error;
@@ -100,6 +100,7 @@ export declare function useSessionState(): {
100
100
  export declare function useOrganizationState(): {
101
101
  activeOrganization: import("vue").Ref<FullOrganization | null, FullOrganization | null>;
102
102
  activeMember: import("vue").Ref<{
103
+ [x: string]: string | number | boolean | string[] | Record<string, any> | (string & Record<never, never>) | Date | number[] | undefined;
103
104
  id: string;
104
105
  organizationId: string;
105
106
  role: "org:admin" | "org:member" | "org:reviewer";
@@ -112,9 +113,8 @@ export declare function useOrganizationState(): {
112
113
  name: string;
113
114
  image?: string | undefined;
114
115
  };
115
- deletedAt?: Date | undefined;
116
- lastActiveAt?: Date | undefined;
117
116
  } | null, {
117
+ [x: string]: string | number | boolean | string[] | Record<string, any> | (string & Record<never, never>) | Date | number[] | undefined;
118
118
  id: string;
119
119
  organizationId: string;
120
120
  role: "org:admin" | "org:member" | "org:reviewer";
@@ -127,8 +127,6 @@ export declare function useOrganizationState(): {
127
127
  name: string;
128
128
  image?: string | undefined;
129
129
  };
130
- deletedAt?: Date | undefined;
131
- lastActiveAt?: Date | undefined;
132
130
  } | null>;
133
131
  };
134
132
  export declare function useApplicationSessionState(): {
@@ -161,5 +159,5 @@ export declare function useApplicationSessionState(): {
161
159
  banExpires?: Date | null | undefined;
162
160
  lastActiveAt?: Date | null | undefined;
163
161
  } | null>;
164
- activeOrganization: import("vue").Ref<Omit<FullOrganization, "members" | "invitations" | "teams"> | null, Omit<FullOrganization, "members" | "invitations" | "teams"> | null>;
162
+ activeOrganization: import("vue").Ref<FullOrganization | null, FullOrganization | null>;
165
163
  };
@@ -17,16 +17,6 @@ function parseTokenExpiry(token) {
17
17
  return null;
18
18
  }
19
19
  }
20
- function mapOrganization(organization) {
21
- return {
22
- name: organization.title,
23
- id: organization.id,
24
- createdAt: organization.createdAt,
25
- logo: organization.avatarUrl,
26
- metadata: organization.metadata,
27
- slug: organization.slug ?? ""
28
- };
29
- }
30
20
  export default defineNuxtPlugin({
31
21
  name: "tela-application-token-refresh",
32
22
  enforce: "post",
@@ -62,14 +52,14 @@ export default defineNuxtPlugin({
62
52
  accessTokenCookie.value = accessToken;
63
53
  refreshTokenCookie.value = refreshToken2;
64
54
  state.user.value = user2;
65
- state.activeOrganization.value = mapOrganization(organization2);
55
+ state.activeOrganization.value = organization2;
66
56
  return;
67
57
  }
68
58
  const { user, organization } = await $fetch("/auth/refresh", {
69
59
  method: "POST"
70
60
  });
71
61
  state.user.value = user;
72
- state.activeOrganization.value = mapOrganization(organization);
62
+ state.activeOrganization.value = organization;
73
63
  } catch {
74
64
  await sdkLogout();
75
65
  if (import.meta.client) {
@@ -107,7 +97,7 @@ export default defineNuxtPlugin({
107
97
  try {
108
98
  const data = await authClient.application.whoAmI(accessTokenCookie.value);
109
99
  state.user.value = data.user;
110
- state.activeOrganization.value = mapOrganization(data.organization);
100
+ state.activeOrganization.value = data.organization;
111
101
  } catch (error) {
112
102
  console.error("[Tela Auth SDK] Failed to get user and organization:", error.message);
113
103
  if (!refreshTokenCookie.value) {
@@ -135,6 +125,17 @@ export default defineNuxtPlugin({
135
125
  return;
136
126
  }
137
127
  if (import.meta.client) {
128
+ if (!state.user.value && accessTokenCookie.value) {
129
+ try {
130
+ const { user, organization } = await $fetch("/auth/whoami", {
131
+ method: "GET"
132
+ });
133
+ state.user.value = user;
134
+ state.activeOrganization.value = organization;
135
+ } catch (error) {
136
+ console.error("[Tela Auth SDK] Failed to load user info on client startup:", error);
137
+ }
138
+ }
138
139
  void scheduleTokenRefresh();
139
140
  }
140
141
  }
@@ -26,14 +26,6 @@ declare const _default: import("h3").EventHandler<import("h3").EventHandlerReque
26
26
  banExpires?: Date | null | undefined;
27
27
  lastActiveAt?: Date | null | undefined;
28
28
  };
29
- organization: {
30
- id: string;
31
- title: string;
32
- slug: string | null;
33
- avatarUrl: string | null;
34
- createdAt: Date;
35
- metadata: string | null;
36
- settings: unknown;
37
- };
29
+ organization: import("@meistrari/auth-core").FullOrganization;
38
30
  }>>;
39
31
  export default _default;
@@ -27,14 +27,6 @@ declare const _default: import("h3").EventHandler<import("h3").EventHandlerReque
27
27
  banExpires?: Date | null | undefined;
28
28
  lastActiveAt?: Date | null | undefined;
29
29
  };
30
- organization: {
31
- id: string;
32
- title: string;
33
- slug: string | null;
34
- avatarUrl: string | null;
35
- createdAt: Date;
36
- metadata: string | null;
37
- settings: unknown;
38
- };
30
+ organization: import("@meistrari/auth-core").FullOrganization;
39
31
  }>>;
40
32
  export default _default;
@@ -0,0 +1,20 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
+ success: boolean;
3
+ user: {
4
+ id: string;
5
+ createdAt: Date;
6
+ updatedAt: Date;
7
+ email: string;
8
+ emailVerified: boolean;
9
+ name: string;
10
+ image?: string | null | undefined;
11
+ twoFactorEnabled: boolean | null | undefined;
12
+ banned: boolean | null | undefined;
13
+ role?: string | null | undefined;
14
+ banReason?: string | null | undefined;
15
+ banExpires?: Date | null | undefined;
16
+ lastActiveAt?: Date | null | undefined;
17
+ };
18
+ organization: import("@meistrari/auth-core").FullOrganization;
19
+ }>>;
20
+ export default _default;
@@ -0,0 +1,31 @@
1
+ import { createError, useRuntimeConfig } from "#imports";
2
+ import { defineEventHandler, getCookie } from "h3";
3
+ import { createNuxtAuthClient } from "../../../shared.js";
4
+ export default defineEventHandler(async (event) => {
5
+ const config = useRuntimeConfig();
6
+ const authConfig = config.public.telaAuth;
7
+ const authClient = createNuxtAuthClient(authConfig.apiUrl, () => null, () => null);
8
+ const accessToken = getCookie(event, "tela-access-token");
9
+ if (!accessToken) {
10
+ throw createError({
11
+ statusCode: 401,
12
+ statusMessage: "Unauthorized",
13
+ message: "No access token found"
14
+ });
15
+ }
16
+ try {
17
+ const { user, organization } = await authClient.application.whoAmI(accessToken);
18
+ return {
19
+ success: true,
20
+ user,
21
+ organization
22
+ };
23
+ } catch (error) {
24
+ console.error("[Auth WhoAmI] Failed to get user and organization:", error);
25
+ throw createError({
26
+ statusCode: 401,
27
+ statusMessage: "Unauthorized",
28
+ message: "Failed to get user and organization"
29
+ });
30
+ }
31
+ });
@@ -3,7 +3,14 @@ import { createRemoteJWKSet, jwtVerify } from "jose";
3
3
  import { useRuntimeConfig } from "nitropack/runtime";
4
4
  export function requireAuth(handler, options) {
5
5
  return defineEventHandler(async (event) => {
6
+ const moduleOptions = useRuntimeConfig(event).public.telaAuth;
7
+ if (!moduleOptions.skipServerMiddleware && !options?.roles && import.meta.dev) {
8
+ console.warn("You have enabled the global server middleware, meaning you only need to use requireAuth() on routes that require specific roles.", `Triggered at ${event.path}`);
9
+ }
6
10
  if (event.context.auth?.user && event.context.auth?.token) {
11
+ if (import.meta.dev) {
12
+ console.debug("Using existing auth context from global server middleware");
13
+ }
7
14
  const user = event.context.auth.user;
8
15
  if (options?.roles && !options.roles.includes(user.role ?? "")) {
9
16
  throw createError({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/auth-nuxt",
3
- "version": "2.2.2",
3
+ "version": "2.3.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -31,7 +31,7 @@
31
31
  "build": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt-module-build build"
32
32
  },
33
33
  "dependencies": {
34
- "@meistrari/auth-core": "1.10.0",
34
+ "@meistrari/auth-core": "1.11.1",
35
35
  "jose": "6.1.3"
36
36
  },
37
37
  "peerDependencies": {