@viridial/shared 1.0.5 → 1.0.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../api/auth.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAGlJ;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;uBACsB,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ9D;;OAEG;iBACgB,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAK1D;;OAEG;cACa,OAAO,CAAC,IAAI,CAAC;IAQ7B;;OAEG;yBACwB,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE;;OAEG;wBACuB,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D;;OAEG;oBACmB,OAAO,CAAC,aAAa,CAAC;IAQ5C;;OAEG;uBACgB,OAAO;CAG3B,CAAA"}
1
+ {"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../api/auth.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAGlJ;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;uBACsB,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAkB9D;;OAEG;iBACgB,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAK1D;;OAEG;cACa,OAAO,CAAC,IAAI,CAAC;IAQ7B;;OAEG;yBACwB,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE;;OAEG;wBACuB,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D;;OAEG;oBACmB,OAAO,CAAC,aAAa,CAAC;IAQ5C;;OAEG;uBACgB,OAAO;CAG3B,CAAA"}
@@ -10,10 +10,20 @@ export const authService = {
10
10
  */
11
11
  async login(credentials) {
12
12
  const response = await httpClient.post(API_ENDPOINTS.AUTH.LOGIN, credentials);
13
- if (response.data?.token) {
14
- tokenUtils.setToken(response.data.token);
13
+ // L'API retourne accessToken ou token
14
+ const token = response.data?.accessToken || response.data?.token;
15
+ if (token) {
16
+ tokenUtils.setToken(token);
15
17
  }
16
- return response.data;
18
+ // Stocker aussi le refreshToken si présent
19
+ if (response.data?.refreshToken) {
20
+ tokenUtils.setRefreshToken(response.data.refreshToken);
21
+ }
22
+ // Normaliser la réponse pour avoir toujours 'token'
23
+ return {
24
+ ...response.data,
25
+ token: token || response.data?.token
26
+ };
17
27
  },
18
28
  /**
19
29
  * Inscription
@@ -1 +1 @@
1
- {"version":3,"file":"http.client.d.ts","sourceRoot":"","sources":["../../api/http.client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAsB,KAAK,kBAAkB,EAAsB,MAAM,OAAO,CAAA;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,oBAAoB,CAAA;AAgB/D;;GAEG;AACH,cAAM,UAAU;IACd,OAAO,CAAC,MAAM,CAAe;gBAEjB,OAAO,CAAC,EAAE,MAAM;IAc5B,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,WAAW;IAcb,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASzE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAStF,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASrF,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASvF,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAQnF;AAED,eAAO,MAAM,UAAU,YAAmB,CAAA"}
1
+ {"version":3,"file":"http.client.d.ts","sourceRoot":"","sources":["../../api/http.client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAsB,KAAK,kBAAkB,EAAsB,MAAM,OAAO,CAAA;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,oBAAoB,CAAA;AAgB/D;;GAEG;AACH,cAAM,UAAU;IACd,OAAO,CAAC,MAAM,CAAe;gBAEjB,OAAO,CAAC,EAAE,MAAM;IAc5B,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,WAAW;IAcb,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASzE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAStF,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASrF,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASvF,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAQnF;AAED,eAAO,MAAM,UAAU,YAAmB,CAAA"}
@@ -42,14 +42,27 @@ class HttpClient {
42
42
  this.client.interceptors.response.use((response) => {
43
43
  return response;
44
44
  }, async (error) => {
45
- if (error.response?.status === 401) {
45
+ const status = error.response?.status;
46
+ if (status === 401) {
46
47
  // Token expiré ou invalide
47
- tokenUtils.removeToken();
48
- // Rediriger vers login
49
- if (typeof window !== 'undefined') {
50
- window.location.href = '/login';
48
+ const token = tokenUtils.getToken();
49
+ if (token) {
50
+ // Token présent mais invalide - nettoyer et rediriger
51
+ tokenUtils.removeToken();
52
+ // Ne rediriger que si on n'est pas déjà sur la page de login
53
+ if (typeof window !== 'undefined' && !window.location.pathname.includes('/login')) {
54
+ // Utiliser un petit délai pour éviter les redirections multiples
55
+ setTimeout(() => {
56
+ window.location.href = '/login';
57
+ }, 100);
58
+ }
51
59
  }
52
60
  }
61
+ else if (status === 403) {
62
+ // Accès refusé - ne pas rediriger automatiquement
63
+ // Laisser les composants gérer cette erreur
64
+ console.warn('Access forbidden:', error.response?.data);
65
+ }
53
66
  return Promise.reject(this.handleError(error));
54
67
  });
55
68
  }
@@ -18,7 +18,7 @@ export declare const API_ENDPOINTS: {
18
18
  readonly USERS: {
19
19
  readonly BASE: "/api/identity/users";
20
20
  readonly BY_ID: (id: number) => string;
21
- readonly PROFILE: "/api/identity/users/profile";
21
+ readonly PROFILE: "/api/identity/users/me";
22
22
  readonly STATS: "/api/identity/users/stats";
23
23
  readonly SEARCH: "/api/identity/users/search";
24
24
  readonly ACTIVITY: (id: number) => string;
@@ -21,7 +21,7 @@ export const API_ENDPOINTS = {
21
21
  USERS: {
22
22
  BASE: '/api/identity/users',
23
23
  BY_ID: (id) => `/api/identity/users/${id}`,
24
- PROFILE: '/api/identity/users/profile',
24
+ PROFILE: '/api/identity/users/me', // Endpoint backend: /me
25
25
  STATS: '/api/identity/users/stats',
26
26
  SEARCH: '/api/identity/users/search',
27
27
  ACTIVITY: (id) => `/api/identity/users/${id}/activity`
@@ -23,7 +23,7 @@ export declare const useAuthStore: import("pinia").StoreDefinition<"auth", Pick<
23
23
  userName: import("vue").ComputedRef<string>;
24
24
  login: (credentials: LoginRequest) => Promise<void>;
25
25
  logout: () => Promise<void>;
26
- checkAuth: () => void;
26
+ checkAuth: () => Promise<void>;
27
27
  setUser: (userData: UserInfo) => void;
28
28
  }, "user" | "isAuthenticated" | "loading">, Pick<{
29
29
  user: import("vue").Ref<{
@@ -46,7 +46,7 @@ export declare const useAuthStore: import("pinia").StoreDefinition<"auth", Pick<
46
46
  userName: import("vue").ComputedRef<string>;
47
47
  login: (credentials: LoginRequest) => Promise<void>;
48
48
  logout: () => Promise<void>;
49
- checkAuth: () => void;
49
+ checkAuth: () => Promise<void>;
50
50
  setUser: (userData: UserInfo) => void;
51
51
  }, "isAdmin" | "isAgent" | "userName">, Pick<{
52
52
  user: import("vue").Ref<{
@@ -69,7 +69,7 @@ export declare const useAuthStore: import("pinia").StoreDefinition<"auth", Pick<
69
69
  userName: import("vue").ComputedRef<string>;
70
70
  login: (credentials: LoginRequest) => Promise<void>;
71
71
  logout: () => Promise<void>;
72
- checkAuth: () => void;
72
+ checkAuth: () => Promise<void>;
73
73
  setUser: (userData: UserInfo) => void;
74
74
  }, "login" | "logout" | "checkAuth" | "setUser">>;
75
75
  //# sourceMappingURL=auth.store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.store.d.ts","sourceRoot":"","sources":["../../stores/auth.store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAIjE;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;yBAmBW,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;kBAarC,OAAO,CAAC,IAAI,CAAC;qBAShB,IAAI;wBAOC,QAAQ,KAAG,IAAI;;;;;;;;;;;;;;;;;;;;yBA7BR,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;kBAarC,OAAO,CAAC,IAAI,CAAC;qBAShB,IAAI;wBAOC,QAAQ,KAAG,IAAI;;;;;;;;;;;;;;;;;;;;yBA7BR,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;kBAarC,OAAO,CAAC,IAAI,CAAC;qBAShB,IAAI;wBAOC,QAAQ,KAAG,IAAI;iDAoB1C,CAAA"}
1
+ {"version":3,"file":"auth.store.d.ts","sourceRoot":"","sources":["../../stores/auth.store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAKjE;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;yBAmBW,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;kBAqDrC,OAAO,CAAC,IAAI,CAAC;qBASV,OAAO,CAAC,IAAI,CAAC;wBA4Cd,QAAQ,KAAG,IAAI;;;;;;;;;;;;;;;;;;;;yBA1GR,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;kBAqDrC,OAAO,CAAC,IAAI,CAAC;qBASV,OAAO,CAAC,IAAI,CAAC;wBA4Cd,QAAQ,KAAG,IAAI;;;;;;;;;;;;;;;;;;;;yBA1GR,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;kBAqDrC,OAAO,CAAC,IAAI,CAAC;qBASV,OAAO,CAAC,IAAI,CAAC;wBA4Cd,QAAQ,KAAG,IAAI;iDAoB1C,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { defineStore } from 'pinia';
2
2
  import { ref, computed } from 'vue';
3
3
  import { authService } from '../api/auth.service';
4
+ import { userService } from '../api/user.service';
4
5
  import { tokenUtils } from '../utils/token.utils';
5
6
  /**
6
7
  * Store d'authentification
@@ -23,9 +24,47 @@ export const useAuthStore = defineStore('auth', () => {
23
24
  async function login(credentials) {
24
25
  loading.value = true;
25
26
  try {
27
+ // 1. Se connecter et obtenir le token
26
28
  const response = await authService.login(credentials);
27
- user.value = response.user;
29
+ // 2. Le token est déjà stocké par authService.login()
30
+ // 3. Marquer comme authentifié immédiatement
28
31
  isAuthenticated.value = true;
32
+ // 4. Récupérer les infos utilisateur depuis le profil
33
+ // Attendre un peu pour que le token soit bien propagé
34
+ await new Promise(resolve => setTimeout(resolve, 100));
35
+ try {
36
+ const profile = await userService.getProfile();
37
+ // Mapper UserProfile vers UserInfo
38
+ // Le backend retourne roleNames (Set<String>) dans UserDTO
39
+ const roleNames = profile.roleNames || profile.roles || [];
40
+ const rolesArray = Array.isArray(roleNames)
41
+ ? roleNames.map((r) => String(r))
42
+ : Array.from(roleNames || []).map((r) => String(r));
43
+ user.value = {
44
+ id: profile.id,
45
+ email: profile.email,
46
+ name: profile.firstName && profile.lastName
47
+ ? `${profile.firstName} ${profile.lastName}`
48
+ : profile.name || profile.email,
49
+ roles: rolesArray,
50
+ organizationId: profile.organizationId
51
+ };
52
+ }
53
+ catch (profileError) {
54
+ // Si l'API profile échoue, on garde quand même l'authentification
55
+ // L'utilisateur sera chargé plus tard par checkAuth()
56
+ const status = profileError?.status || profileError?.response?.status;
57
+ if (status === 401 || status === 403) {
58
+ // Erreur d'authentification - ne pas continuer
59
+ console.error('Authentication failed when fetching profile:', profileError);
60
+ throw profileError;
61
+ }
62
+ else {
63
+ // Autre erreur (réseau, serveur, etc.) - on continue sans user
64
+ console.warn('Failed to fetch user profile after login (non-auth error):', profileError);
65
+ // On reste authentifié même sans user pour l'instant
66
+ }
67
+ }
29
68
  }
30
69
  catch (error) {
31
70
  throw error;
@@ -43,10 +82,49 @@ export const useAuthStore = defineStore('auth', () => {
43
82
  isAuthenticated.value = false;
44
83
  }
45
84
  }
46
- function checkAuth() {
85
+ async function checkAuth() {
47
86
  if (tokenUtils.hasToken()) {
48
87
  isAuthenticated.value = true;
49
- // TODO: Récupérer les infos utilisateur depuis le token ou API
88
+ // Récupérer les infos utilisateur depuis l'API si pas déjà chargé
89
+ if (!user.value) {
90
+ try {
91
+ const profile = await userService.getProfile();
92
+ // Le backend retourne roleNames (Set<String>) dans UserDTO
93
+ const roleNames = profile.roleNames || profile.roles || [];
94
+ const rolesArray = Array.isArray(roleNames)
95
+ ? roleNames.map((r) => String(r))
96
+ : Array.from(roleNames || []).map((r) => String(r));
97
+ user.value = {
98
+ id: profile.id,
99
+ email: profile.email,
100
+ name: profile.firstName && profile.lastName
101
+ ? `${profile.firstName} ${profile.lastName}`
102
+ : profile.name || profile.email,
103
+ roles: rolesArray,
104
+ organizationId: profile.organizationId
105
+ };
106
+ }
107
+ catch (error) {
108
+ const status = error?.status || error?.response?.status;
109
+ if (status === 401 || status === 403) {
110
+ // Token invalide ou expiré
111
+ console.error('Authentication failed in checkAuth:', error);
112
+ tokenUtils.removeToken();
113
+ isAuthenticated.value = false;
114
+ user.value = null;
115
+ }
116
+ else {
117
+ // Autre erreur (réseau, serveur, etc.)
118
+ console.warn('Failed to fetch user profile in checkAuth (non-auth error):', error);
119
+ // On garde l'authentification mais sans user
120
+ // Le token est valide, donc on reste authentifié
121
+ }
122
+ }
123
+ }
124
+ }
125
+ else {
126
+ isAuthenticated.value = false;
127
+ user.value = null;
50
128
  }
51
129
  }
52
130
  function setUser(userData) {
@@ -6,9 +6,12 @@ export interface LoginRequest {
6
6
  password: string;
7
7
  }
8
8
  export interface LoginResponse {
9
- token: string;
9
+ accessToken?: string;
10
+ token?: string;
10
11
  refreshToken?: string;
11
- user: UserInfo;
12
+ tokenType?: string;
13
+ expiresIn?: number;
14
+ user?: UserInfo;
12
15
  }
13
16
  export interface SignupRequest {
14
17
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.types.d.ts","sourceRoot":"","sources":["../../types/auth.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB"}
1
+ {"version":3,"file":"auth.types.d.ts","sourceRoot":"","sources":["../../types/auth.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viridial/shared",
3
- "version": "1.0.5",
3
+ "version": "1.0.8",
4
4
  "type": "module",
5
5
  "description": "Shared modules for Real Estate frontend applications - Vue 3, TypeScript, Pinia, Axios",
6
6
  "main": "./dist/index.js",