@meistrari/auth-nuxt 0.2.0 → 1.0.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.
@@ -0,0 +1,29 @@
1
+ import { useCookie, useRuntimeConfig } from "#app";
2
+ import { createNuxtAuthClient } from "../shared.js";
3
+ export function useTelaApiKey() {
4
+ const { jwtCookieName, apiUrl } = useRuntimeConfig().public.telaAuth;
5
+ const tokenCookie = useCookie(jwtCookieName);
6
+ const authClient = createNuxtAuthClient(apiUrl, () => tokenCookie.value ?? null);
7
+ async function createApiKey(payload) {
8
+ return authClient.apiKey.createApiKey(payload);
9
+ }
10
+ async function updateApiKey(payload) {
11
+ return authClient.apiKey.updateApiKey(payload);
12
+ }
13
+ async function deleteApiKey(id) {
14
+ return authClient.apiKey.deleteApiKey(id);
15
+ }
16
+ async function listApiKeys() {
17
+ return authClient.apiKey.listApiKeys();
18
+ }
19
+ async function getApiKey(id) {
20
+ return authClient.apiKey.getApiKey(id);
21
+ }
22
+ return {
23
+ createApiKey,
24
+ updateApiKey,
25
+ deleteApiKey,
26
+ listApiKeys,
27
+ getApiKey
28
+ };
29
+ }
@@ -0,0 +1,115 @@
1
+ import type { Ref } from 'vue';
2
+ import type { CreateTeamPayload, FullOrganization, Invitation, InviteUserToOrganizationOptions, ListMembersOptions, Member, RemoveUserFromOrganizationOptions, Team, TeamMember, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload } from '@meistrari/auth-core';
3
+ import { type FullOrganizationWithRelations } from './state.js';
4
+ export interface UseTelaOrganizationReturn {
5
+ /** Reactive reference to the active organization with members, invitations, and teams. */
6
+ activeOrganization: Ref<FullOrganizationWithRelations | null>;
7
+ /** Reactive reference to the current user's membership in the active organization. */
8
+ activeMember: Ref<Member | null>;
9
+ /**
10
+ * Retrieves the active organization for the current user session and updates the active organization state.
11
+ * @returns The active organization with members, invitations, and teams
12
+ */
13
+ getActiveOrganization: () => Promise<FullOrganizationWithRelations | undefined>;
14
+ /**
15
+ * Lists all organizations for the current user session.
16
+ * @returns A list of organizations
17
+ */
18
+ listOrganizations: () => Promise<FullOrganization[]>;
19
+ /**
20
+ * Sets the active organization for the current user session and updates the active organization state.
21
+ * @param id - The ID of the organization to set as active
22
+ */
23
+ setActiveOrganization: (id: string) => Promise<void>;
24
+ /**
25
+ * Updates the active organization for the current user session and updates the active organization state.
26
+ * @param payload - The organization fields to update
27
+ * @returns The updated organization
28
+ */
29
+ updateOrganization: (payload: UpdateOrganizationPayload) => Promise<FullOrganization>;
30
+ /**
31
+ * Lists the members of the active organization.
32
+ * @param options - Pagination options
33
+ * @returns A list of members
34
+ */
35
+ listMembers: (options?: ListMembersOptions) => Promise<Member[]>;
36
+ /**
37
+ * Retrieves the active member of the current user session.
38
+ * @returns The active member
39
+ */
40
+ getActiveMember: () => Promise<Member>;
41
+ /**
42
+ * Invites a user to the active organization.
43
+ * @param options - Invitation configuration
44
+ * @returns The invitation
45
+ */
46
+ inviteUserToOrganization: (options: InviteUserToOrganizationOptions) => Promise<Invitation>;
47
+ /**
48
+ * Accepts an organization invitation and updates the active organization state.
49
+ * @param id - The invitation ID to accept
50
+ */
51
+ acceptInvitation: (id: string) => Promise<void>;
52
+ /**
53
+ * Cancels a pending organization invitation and updates the active organization state.
54
+ * @param id - The invitation ID to cancel
55
+ */
56
+ cancelInvitation: (id: string) => Promise<void>;
57
+ /**
58
+ * Removes a user from the active organization.
59
+ * @param options - User identifier (either memberId or userEmail must be provided)
60
+ */
61
+ removeUserFromOrganization: (options: RemoveUserFromOrganizationOptions) => Promise<void>;
62
+ /**
63
+ * Updates the role of an organization member.
64
+ * @param options - Role update configuration
65
+ */
66
+ updateMemberRole: (options: UpdateMemberRoleOptions) => Promise<void>;
67
+ /**
68
+ * Creates a new team within the active organization.
69
+ * @param payload - Team configuration
70
+ * @returns The created team
71
+ */
72
+ createTeam: (payload: CreateTeamPayload) => Promise<Team>;
73
+ /**
74
+ * Updates an existing team's details.
75
+ * @param id - The team ID to update
76
+ * @param payload - Team fields to update
77
+ * @returns The updated team
78
+ */
79
+ updateTeam: (id: string, payload: UpdateTeamPayload) => Promise<Team>;
80
+ /**
81
+ * Deletes a team from the active organization.
82
+ * @param id - The team ID to delete
83
+ */
84
+ deleteTeam: (id: string) => Promise<void>;
85
+ /**
86
+ * Lists all teams in the active organization.
87
+ * @returns An array of teams
88
+ */
89
+ listTeams: () => Promise<Team[]>;
90
+ /**
91
+ * Lists all members of a specific team.
92
+ * @param id - The team ID
93
+ * @returns An array of team members
94
+ */
95
+ listTeamMembers: (id: string) => Promise<TeamMember[]>;
96
+ /**
97
+ * Adds a user to a team.
98
+ * @param teamId - The team ID
99
+ * @param userId - The user ID to add
100
+ * @returns The added team member
101
+ */
102
+ addTeamMember: (teamId: string, userId: string) => Promise<TeamMember>;
103
+ /**
104
+ * Removes a user from a team.
105
+ * @param teamId - The team ID
106
+ * @param userId - The user ID to remove
107
+ */
108
+ removeTeamMember: (teamId: string, userId: string) => Promise<void>;
109
+ }
110
+ /**
111
+ * Composable for managing organizations and their members, invitations, and teams.
112
+ *
113
+ * @returns An object containing organization management functions and the active organization and member states.
114
+ */
115
+ export declare function useTelaOrganization(): UseTelaOrganizationReturn;
@@ -0,0 +1,164 @@
1
+ import { useCookie, useRuntimeConfig } from "#app";
2
+ import { createNuxtAuthClient } from "../shared.js";
3
+ import { useOrganizationState, useSessionState } from "./state.js";
4
+ export function useTelaOrganization() {
5
+ const { activeOrganization, activeMember } = useOrganizationState();
6
+ const { session } = useSessionState();
7
+ const { jwtCookieName, apiUrl } = useRuntimeConfig().public.telaAuth;
8
+ const tokenCookie = useCookie(jwtCookieName);
9
+ const authClient = createNuxtAuthClient(apiUrl, () => tokenCookie.value ?? null);
10
+ async function getActiveOrganization() {
11
+ if (!session.value?.activeOrganizationId) {
12
+ return;
13
+ }
14
+ const organization = await authClient.organization.getOrganization(
15
+ session.value?.activeOrganizationId,
16
+ {
17
+ includeMembers: true,
18
+ includeInvitations: true,
19
+ includeTeams: true
20
+ }
21
+ );
22
+ activeOrganization.value = organization;
23
+ return organization;
24
+ }
25
+ async function listOrganizations() {
26
+ return authClient.organization.listOrganizations();
27
+ }
28
+ async function setActiveOrganization(id) {
29
+ await authClient.organization.setActiveOrganization(id);
30
+ const organization = await authClient.organization.getOrganization(id, {
31
+ includeMembers: true,
32
+ includeInvitations: true,
33
+ includeTeams: true
34
+ });
35
+ activeOrganization.value = organization;
36
+ }
37
+ async function updateOrganization(payload) {
38
+ if (!activeOrganization.value) {
39
+ throw new Error("No active organization found");
40
+ }
41
+ const organization = await authClient.organization.updateOrganization(payload);
42
+ activeOrganization.value = { ...activeOrganization.value, ...organization };
43
+ return organization;
44
+ }
45
+ async function listMembers(options) {
46
+ return authClient.organization.listMembers(options);
47
+ }
48
+ async function getActiveMember() {
49
+ const member = await authClient.organization.getActiveMember();
50
+ activeMember.value = member;
51
+ return member;
52
+ }
53
+ async function inviteUserToOrganization(options) {
54
+ const invitation = await authClient.organization.inviteUserToOrganization(options);
55
+ if (activeOrganization.value) {
56
+ activeOrganization.value = {
57
+ ...activeOrganization.value,
58
+ invitations: [...activeOrganization.value?.invitations ?? [], invitation]
59
+ };
60
+ }
61
+ return invitation;
62
+ }
63
+ async function acceptInvitation(id) {
64
+ await authClient.organization.acceptInvitation(id);
65
+ const members = await authClient.organization.listMembers();
66
+ if (activeOrganization.value) {
67
+ activeOrganization.value = {
68
+ ...activeOrganization.value,
69
+ members
70
+ };
71
+ }
72
+ }
73
+ async function cancelInvitation(id) {
74
+ await authClient.organization.cancelInvitation(id);
75
+ if (activeOrganization.value) {
76
+ activeOrganization.value = {
77
+ ...activeOrganization.value,
78
+ invitations: activeOrganization.value?.invitations?.filter((invitation) => invitation.id !== id) ?? []
79
+ };
80
+ }
81
+ }
82
+ async function removeUserFromOrganization(options) {
83
+ await authClient.organization.removeUserFromOrganization(options);
84
+ if (activeOrganization.value) {
85
+ activeOrganization.value = {
86
+ ...activeOrganization.value,
87
+ members: activeOrganization.value?.members?.filter((member) => member.id !== options.memberId) ?? []
88
+ };
89
+ }
90
+ }
91
+ async function updateMemberRole(options) {
92
+ await authClient.organization.updateMemberRole(options);
93
+ const members = await authClient.organization.listMembers();
94
+ if (activeOrganization.value) {
95
+ activeOrganization.value = {
96
+ ...activeOrganization.value,
97
+ members
98
+ };
99
+ }
100
+ }
101
+ async function createTeam(payload) {
102
+ const team = await authClient.organization.createTeam(payload);
103
+ if (activeOrganization.value) {
104
+ activeOrganization.value = {
105
+ ...activeOrganization.value,
106
+ teams: [...activeOrganization.value?.teams ?? [], team]
107
+ };
108
+ }
109
+ return team;
110
+ }
111
+ async function updateTeam(id, payload) {
112
+ const updatedTeam = await authClient.organization.updateTeam(id, payload);
113
+ if (activeOrganization.value) {
114
+ activeOrganization.value = {
115
+ ...activeOrganization.value,
116
+ teams: activeOrganization.value?.teams?.map((team) => team.id === id ? updatedTeam : team) ?? []
117
+ };
118
+ }
119
+ return updatedTeam;
120
+ }
121
+ async function deleteTeam(id) {
122
+ await authClient.organization.deleteTeam(id);
123
+ if (activeOrganization.value) {
124
+ activeOrganization.value = {
125
+ ...activeOrganization.value,
126
+ teams: activeOrganization.value?.teams?.filter((team) => team.id !== id) ?? []
127
+ };
128
+ }
129
+ }
130
+ async function listTeams() {
131
+ return authClient.organization.listTeams();
132
+ }
133
+ async function listTeamMembers(id) {
134
+ return authClient.organization.listTeamMembers(id);
135
+ }
136
+ async function addTeamMember(teamId, userId) {
137
+ return authClient.organization.addTeamMember(teamId, userId);
138
+ }
139
+ async function removeTeamMember(teamId, userId) {
140
+ await authClient.organization.removeTeamMember(teamId, userId);
141
+ }
142
+ return {
143
+ activeOrganization,
144
+ activeMember,
145
+ getActiveOrganization,
146
+ listOrganizations,
147
+ setActiveOrganization,
148
+ updateOrganization,
149
+ listMembers,
150
+ getActiveMember,
151
+ inviteUserToOrganization,
152
+ acceptInvitation,
153
+ cancelInvitation,
154
+ removeUserFromOrganization,
155
+ updateMemberRole,
156
+ createTeam,
157
+ updateTeam,
158
+ deleteTeam,
159
+ listTeams,
160
+ listTeamMembers,
161
+ addTeamMember,
162
+ removeTeamMember
163
+ };
164
+ }
@@ -0,0 +1,63 @@
1
+ import type { Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, User } from '@meistrari/auth-core';
2
+ import type { Ref } from 'vue';
3
+ export interface UseTelaSessionReturn {
4
+ /** Reactive reference to the current user. Null if not authenticated. */
5
+ user: Ref<User | null>;
6
+ /** Reactive reference to the current session. Null if not authenticated. */
7
+ session: Ref<Session | null>;
8
+ /**
9
+ * Retrieves the current user session.
10
+ * @returns The current user session
11
+ */
12
+ getSession: () => Promise<{
13
+ user: User;
14
+ session: Session;
15
+ } | null>;
16
+ /**
17
+ * Retrieves a valid JWT token.
18
+ * @returns The JWT token, or null if not authenticated
19
+ */
20
+ getToken: () => Promise<string | null>;
21
+ /**
22
+ * Authenticates a user with email and password credentials.
23
+ * @param options - Email/password sign-in configuration
24
+ */
25
+ signInWithEmailAndPassword: (options: SignInWithEmailAndPasswordOptions) => Promise<void>;
26
+ /**
27
+ * Initiates social authentication flow with Google or Microsoft.
28
+ * @param options - Social sign-in configuration
29
+ * @throws {InvalidSocialProvider} When the provider is not 'google' or 'microsoft'
30
+ * @throws {InvalidCallbackURL} When callback URLs are malformed
31
+ */
32
+ signInWithSocialProvider: (options: SocialSignInOptions) => Promise<void>;
33
+ /**
34
+ * Initiates SAML-based Single Sign-On authentication flow.
35
+ * @param options - SAML sign-in configuration
36
+ * @throws {EmailRequired} When email is not provided
37
+ * @throws {InvalidCallbackURL} When callback URLs are malformed
38
+ */
39
+ signInWithSaml: (options: SignInWithSamlOptions) => Promise<void>;
40
+ /**
41
+ * Signs out the currently authenticated user.
42
+ * @param callback - Optional callback function to execute after signing out
43
+ */
44
+ signOut: (callback?: (() => void) | (() => Promise<void>)) => Promise<void>;
45
+ /**
46
+ * Initiates a password reset request by sending a reset email.
47
+ * @param email - Email address of the user requesting password reset
48
+ * @param callbackURL - URL where the user will be redirected to complete the reset
49
+ */
50
+ requestPasswordReset: (email: string, callbackURL: string) => Promise<void>;
51
+ /**
52
+ * Completes the password reset process with a reset token and new password.
53
+ * @param token - The password reset token from the email
54
+ * @param password - The new password to set
55
+ */
56
+ resetPassword: (token: string, password: string) => Promise<void>;
57
+ }
58
+ /**
59
+ * Composable for managing user sessions and authentication.
60
+ *
61
+ * @returns An object containing session management functions and the user and session states.
62
+ */
63
+ export declare function useTelaSession(): UseTelaSessionReturn;
@@ -0,0 +1,88 @@
1
+ import { useCookie, useRuntimeConfig } from "#app";
2
+ import { APIError } from "@meistrari/auth-core";
3
+ import { createNuxtAuthClient } from "../shared.js";
4
+ import { useOrganizationState, useSessionState } from "./state.js";
5
+ export function useTelaSession() {
6
+ const { user, session } = useSessionState();
7
+ const { jwtCookieName, apiUrl } = useRuntimeConfig().public.telaAuth;
8
+ const tokenCookie = useCookie(jwtCookieName);
9
+ const authClient = createNuxtAuthClient(apiUrl, () => tokenCookie.value ?? null);
10
+ async function getSession() {
11
+ return await authClient.session.getSession();
12
+ }
13
+ async function getToken() {
14
+ try {
15
+ const { token } = await authClient.session.getToken();
16
+ return token;
17
+ } catch (error) {
18
+ if (error instanceof APIError && error.status === 401) {
19
+ await signOut();
20
+ }
21
+ return null;
22
+ }
23
+ }
24
+ async function signInWithSocialProvider({
25
+ provider,
26
+ callbackURL,
27
+ errorCallbackURL
28
+ }) {
29
+ await authClient.session.signInWithSocialProvider({
30
+ provider,
31
+ callbackURL,
32
+ errorCallbackURL
33
+ });
34
+ }
35
+ async function signInWithSaml({
36
+ email,
37
+ callbackURL,
38
+ errorCallbackURL
39
+ }) {
40
+ await authClient.session.signInWithSaml({
41
+ email,
42
+ callbackURL,
43
+ errorCallbackURL
44
+ });
45
+ }
46
+ async function signInWithEmailAndPassword({
47
+ email,
48
+ password,
49
+ callbackURL,
50
+ errorCallbackURL
51
+ }) {
52
+ await authClient.session.signInWithEmailAndPassword({
53
+ email,
54
+ password,
55
+ callbackURL,
56
+ errorCallbackURL
57
+ });
58
+ }
59
+ async function requestPasswordReset(email, callbackURL) {
60
+ await authClient.session.requestPasswordReset(email, callbackURL);
61
+ }
62
+ async function resetPassword(token, password) {
63
+ await authClient.session.resetPassword(token, password);
64
+ }
65
+ async function signOut(callback) {
66
+ const { activeOrganization, activeMember } = useOrganizationState();
67
+ await authClient.session.signOut(async () => {
68
+ tokenCookie.value = null;
69
+ user.value = null;
70
+ session.value = null;
71
+ activeOrganization.value = null;
72
+ activeMember.value = null;
73
+ await callback?.();
74
+ });
75
+ }
76
+ return {
77
+ user,
78
+ session,
79
+ getSession,
80
+ getToken,
81
+ signInWithEmailAndPassword,
82
+ signInWithSocialProvider,
83
+ signInWithSaml,
84
+ signOut,
85
+ requestPasswordReset,
86
+ resetPassword
87
+ };
88
+ }
@@ -0,0 +1,22 @@
1
+ import type { FullOrganization, Invitation, Member, Team } from '@meistrari/auth-core';
2
+ export type FullOrganizationWithRelations = FullOrganization & {
3
+ members: Member[];
4
+ invitations: Invitation[];
5
+ teams: Team[];
6
+ };
7
+ /**
8
+ * Shared state for session management.
9
+ * This module provides access to session-related state without creating circular dependencies.
10
+ */
11
+ export declare function useSessionState(): {
12
+ user: import("vue").Ref<any, any>;
13
+ session: import("vue").Ref<any, any>;
14
+ };
15
+ /**
16
+ * Shared state for organization management.
17
+ * This module provides access to organization-related state without creating circular dependencies.
18
+ */
19
+ export declare function useOrganizationState(): {
20
+ activeOrganization: import("vue").Ref<any, any>;
21
+ activeMember: import("vue").Ref<any, any>;
22
+ };
@@ -0,0 +1,17 @@
1
+ import { useState } from "#app";
2
+ export function useSessionState() {
3
+ const user = useState("user", () => null);
4
+ const session = useState("session", () => null);
5
+ return {
6
+ user,
7
+ session
8
+ };
9
+ }
10
+ export function useOrganizationState() {
11
+ const activeOrganization = useState("activeOrganization", () => null);
12
+ const activeMember = useState("activeMember", () => null);
13
+ return {
14
+ activeOrganization,
15
+ activeMember
16
+ };
17
+ }
@@ -1,15 +1,2 @@
1
- import { createAuthClient } from '@meistrari/auth-core';
2
- declare const _default: import("#app").Plugin<{
3
- auth: {
4
- client: ReturnType<typeof createAuthClient>;
5
- getToken: () => Promise<string | null | undefined>;
6
- refreshToken: () => Promise<string | null | undefined>;
7
- };
8
- }> & import("#app").ObjectPlugin<{
9
- auth: {
10
- client: ReturnType<typeof createAuthClient>;
11
- getToken: () => Promise<string | null | undefined>;
12
- refreshToken: () => Promise<string | null | undefined>;
13
- };
14
- }>;
1
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
15
2
  export default _default;