@arkitektbedriftene/fe-lib 6.0.0 → 6.1.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,53 @@
1
+ import { SigninPopupArgs, SigninRedirectArgs, SigninSilentArgs, SignoutRedirectArgs, User, UserManagerSettings } from 'oidc-client-ts';
2
+ export type UserInfo = {
3
+ email: string;
4
+ firmaccess: string;
5
+ firstname: string;
6
+ lastname: string;
7
+ username: string;
8
+ fc: string;
9
+ externalid: string;
10
+ role: string;
11
+ };
12
+ export type ImpersonationData = {
13
+ impersonatedUser: UserInfo;
14
+ impersonationToken: string;
15
+ };
16
+ /**
17
+ * A simpler wrapper around UserManager that combines normal authentication
18
+ * with impersonation functionality without React context dependency.
19
+ */
20
+ export declare class AuthManager {
21
+ private userManager;
22
+ private storageKey;
23
+ constructor(settings: UserManagerSettings);
24
+ /**
25
+ * Get impersonation user from localStorage
26
+ */
27
+ getImpersonationData(): ImpersonationData | null;
28
+ /**
29
+ * Get the current user, preferring impersonated user if available
30
+ */
31
+ getUser(): Promise<({
32
+ access_token: string;
33
+ profile: UserInfo;
34
+ impersonating: boolean;
35
+ }) | null>;
36
+ signinRedirect(args?: SigninRedirectArgs): Promise<void>;
37
+ signinPopup(args?: SigninPopupArgs): Promise<User>;
38
+ signinSilent(args?: SigninSilentArgs): Promise<User | null>;
39
+ signinCallback(): Promise<User | null>;
40
+ signoutRedirect(args?: SignoutRedirectArgs): Promise<void>;
41
+ /**
42
+ * Set impersonation with access token
43
+ */
44
+ setImpersonation(accessToken: string): void;
45
+ /**
46
+ * Clear impersonation and return to normal user
47
+ */
48
+ clearImpersonation(): void;
49
+ /**
50
+ * Handle impersonation callback from URL parameters
51
+ */
52
+ handleImpersonationCallback(urlStr: string): void;
53
+ }
@@ -3,6 +3,7 @@ import { Context, ReactNode } from 'react';
3
3
  export * from 'oidc-client-ts';
4
4
  export * from './impersonate';
5
5
  export * from './firmAccess';
6
+ export * from './AuthManager';
6
7
  export type AuthState = {
7
8
  user: User | null;
8
9
  isLoading: boolean;
package/dist/oidc.es.js CHANGED
@@ -1,235 +1,328 @@
1
- import { jsx as C } from "react/jsx-runtime";
2
- import { createContext as x, useContext as E, useMemo as v, useEffect as h, useState as k, useRef as U, useCallback as d } from "react";
1
+ var v = Object.defineProperty;
2
+ var R = (t, e, r) => e in t ? v(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
+ var g = (t, e, r) => R(t, typeof e != "symbol" ? e + "" : e, r);
4
+ import { jsx as A } from "react/jsx-runtime";
5
+ import { createContext as I, useContext as k, useMemo as U, useEffect as f, useState as L, useRef as x, useCallback as d } from "react";
6
+ import { UserManager as P } from "oidc-client-ts";
3
7
  export * from "oidc-client-ts";
4
- import L from "use-local-storage-state";
5
- import { jwtDecode as P } from "jwt-decode";
6
- const I = x(
8
+ import T from "use-local-storage-state";
9
+ import { jwtDecode as y } from "jwt-decode";
10
+ const E = I(
7
11
  null
8
- ), g = () => {
9
- const t = E(I);
12
+ ), b = () => {
13
+ const t = k(E);
10
14
  if (!t)
11
15
  throw new Error(
12
16
  "useImpersonationContext must be used within a ImpersonationContextProvider"
13
17
  );
14
18
  return t;
15
- }, z = ({
19
+ }, V = ({
16
20
  children: t
17
21
  }) => {
18
- const [e, c] = L("impersonationState", {
22
+ const [e, r] = T("impersonationState", {
19
23
  defaultValue: {}
20
- }), s = v(() => ({
24
+ }), s = U(() => ({
21
25
  accessToken: e == null ? void 0 : e.accessToken,
22
26
  userInfo: e == null ? void 0 : e.userInfo,
23
- setImpersonation: (n, o) => {
24
- c({ accessToken: n, userInfo: o });
27
+ setImpersonation: (o, i) => {
28
+ r({ accessToken: o, userInfo: i });
25
29
  }
26
30
  }), []);
27
- return /* @__PURE__ */ C(I.Provider, { value: s, children: t });
28
- }, N = (t) => {
29
- const { setImpersonation: e } = g();
30
- h(() => {
31
- const { search: c } = window.location, s = new URLSearchParams(c).get(
31
+ return /* @__PURE__ */ A(E.Provider, { value: s, children: t });
32
+ }, q = (t) => {
33
+ const { setImpersonation: e } = b();
34
+ f(() => {
35
+ const { search: r } = window.location, s = new URLSearchParams(r).get(
32
36
  "impersonateAccessToken"
33
37
  );
34
38
  if (s && e) {
35
- const n = P(s);
36
- e(s, n), t();
39
+ const o = y(s);
40
+ e(s, o), t();
37
41
  }
38
42
  }, []);
39
43
  };
40
- function V(t) {
44
+ function B(t) {
41
45
  return JSON.parse(t).map((s) => {
42
46
  const [
43
- n,
44
47
  o,
45
- u,
46
48
  i,
49
+ u,
50
+ a,
47
51
  l
48
- ] = s.split("|"), m = i.split(",");
52
+ ] = s.split("|"), m = a.split(",");
49
53
  return {
50
- CustomerExternalId: n,
51
- CustomerFirmId: o,
54
+ CustomerExternalId: o,
55
+ CustomerFirmId: i,
52
56
  CustomerFirmName: u,
53
57
  CustomerUserRoles: m,
54
58
  CustomerUserIsAdmin: l === "True" || l === "1"
55
59
  };
56
60
  });
57
61
  }
58
- const J = [
62
+ const G = [
59
63
  "97",
60
64
  "131",
61
65
  "132",
62
66
  "141"
63
- ], K = [
67
+ ], H = [
64
68
  "3"
65
- ], _ = [
69
+ ], Q = [
66
70
  "0"
67
- ], y = ({
71
+ ];
72
+ class W {
73
+ constructor(e) {
74
+ g(this, "userManager");
75
+ g(this, "storageKey", "impersonationState");
76
+ this.userManager = new P(e);
77
+ }
78
+ /**
79
+ * Get impersonation user from localStorage
80
+ */
81
+ getImpersonationData() {
82
+ try {
83
+ const e = localStorage.getItem(this.storageKey);
84
+ if (e) {
85
+ const r = JSON.parse(e);
86
+ if (r.impersonationToken && r.impersonatedUser)
87
+ return r;
88
+ }
89
+ } catch (e) {
90
+ console.error("Failed to load impersonation from storage:", e);
91
+ }
92
+ return null;
93
+ }
94
+ /**
95
+ * Get the current user, preferring impersonated user if available
96
+ */
97
+ async getUser() {
98
+ const e = this.getImpersonationData();
99
+ if (e)
100
+ return {
101
+ access_token: e.impersonationToken,
102
+ profile: e.impersonatedUser,
103
+ impersonating: !0
104
+ };
105
+ const r = await this.userManager.getUser();
106
+ return !r || r.expired ? null : {
107
+ access_token: r.access_token,
108
+ profile: r.profile,
109
+ impersonating: !1
110
+ };
111
+ }
112
+ async signinRedirect(e) {
113
+ await this.userManager.signinRedirect(e);
114
+ }
115
+ async signinPopup(e) {
116
+ return await this.userManager.signinPopup(e);
117
+ }
118
+ async signinSilent(e) {
119
+ return await this.userManager.signinSilent(e);
120
+ }
121
+ async signinCallback() {
122
+ const e = await this.userManager.signinCallback();
123
+ return e || null;
124
+ }
125
+ async signoutRedirect(e) {
126
+ this.clearImpersonation(), await this.userManager.signoutRedirect(e);
127
+ }
128
+ // Impersonation methods
129
+ /**
130
+ * Set impersonation with access token
131
+ */
132
+ setImpersonation(e) {
133
+ try {
134
+ const s = {
135
+ impersonatedUser: y(e),
136
+ impersonationToken: e
137
+ };
138
+ localStorage.setItem(this.storageKey, JSON.stringify(s));
139
+ } catch (r) {
140
+ console.error("Failed to decode impersonation token:", r);
141
+ }
142
+ }
143
+ /**
144
+ * Clear impersonation and return to normal user
145
+ */
146
+ clearImpersonation() {
147
+ localStorage.removeItem(this.storageKey);
148
+ }
149
+ /**
150
+ * Handle impersonation callback from URL parameters
151
+ */
152
+ handleImpersonationCallback(e) {
153
+ const s = new URL(e).searchParams.get("impersonateAccessToken");
154
+ if (!s)
155
+ throw new Error("Missing url param 'impersonateAccessToken'");
156
+ this.setImpersonation(s);
157
+ }
158
+ }
159
+ const O = ({
68
160
  userManager: t,
69
161
  context: e,
70
- children: c
162
+ children: r
71
163
  }) => {
72
- const [s, n] = k({
164
+ const [s, o] = L({
73
165
  user: null,
74
166
  isLoading: !0,
75
167
  isAuthenticated: !1,
76
168
  isError: !1,
77
169
  error: null
78
- }), o = U(!1);
79
- h(() => {
80
- o.current || (o.current = !0, (async () => {
170
+ }), i = x(!1);
171
+ f(() => {
172
+ i.current || (i.current = !0, (async () => {
81
173
  try {
82
- const r = await t.getUser();
83
- n({
84
- user: r,
174
+ const n = await t.getUser();
175
+ o({
176
+ user: n,
85
177
  isLoading: !1,
86
- isAuthenticated: r ? !r.expired : !1,
178
+ isAuthenticated: n ? !n.expired : !1,
87
179
  isError: !1,
88
180
  error: null
89
181
  });
90
- } catch (r) {
91
- n({
182
+ } catch (n) {
183
+ o({
92
184
  user: null,
93
185
  isLoading: !1,
94
186
  isAuthenticated: !1,
95
187
  isError: !0,
96
- error: r instanceof Error ? r : new Error("Unknown error during auth")
188
+ error: n instanceof Error ? n : new Error("Unknown error during auth")
97
189
  });
98
190
  }
99
191
  })());
100
- }, [t]), h(() => {
101
- const r = (f) => {
102
- n({
103
- user: f,
192
+ }, [t]), f(() => {
193
+ const n = (p) => {
194
+ o({
195
+ user: p,
104
196
  isLoading: !1,
105
- isAuthenticated: !f.expired,
197
+ isAuthenticated: !p.expired,
106
198
  isError: !1,
107
199
  error: null
108
200
  });
109
201
  };
110
- t.events.addUserLoaded(r);
111
- const a = () => {
112
- n({
202
+ t.events.addUserLoaded(n);
203
+ const c = () => {
204
+ o({
113
205
  ...s,
114
206
  user: null,
115
207
  isAuthenticated: !1
116
208
  });
117
209
  };
118
- t.events.addUserUnloaded(a);
119
- const w = (f) => {
120
- n({
210
+ t.events.addUserUnloaded(c);
211
+ const w = (p) => {
212
+ o({
121
213
  ...s,
122
214
  isLoading: !1,
123
215
  isError: !0,
124
- error: f
216
+ error: p
125
217
  });
126
218
  };
127
219
  return t.events.addSilentRenewError(w), () => {
128
- t.events.removeUserLoaded(r), t.events.removeUserUnloaded(a), t.events.removeSilentRenewError(w);
220
+ t.events.removeUserLoaded(n), t.events.removeUserUnloaded(c), t.events.removeSilentRenewError(w);
129
221
  };
130
222
  }, [t]);
131
223
  const u = d(async () => {
132
- const r = await t.signinCallback();
133
- return n({
134
- user: r ?? null,
224
+ const n = await t.signinCallback();
225
+ return o({
226
+ user: n ?? null,
135
227
  isLoading: !1,
136
- isAuthenticated: r ? !r.expired : !1,
228
+ isAuthenticated: n ? !n.expired : !1,
137
229
  isError: !1,
138
230
  error: null
139
- }), r ?? void 0;
140
- }, [t]), i = d(
141
- async (r) => {
231
+ }), n ?? void 0;
232
+ }, [t]), a = d(
233
+ async (n) => {
142
234
  try {
143
- await t.signinRedirect(r);
144
- } catch (a) {
145
- console.error(a);
235
+ await t.signinRedirect(n);
236
+ } catch (c) {
237
+ console.error(c);
146
238
  }
147
239
  },
148
240
  [t]
149
241
  ), l = d(
150
- async (r) => await t.signinPopup(r),
242
+ async (n) => await t.signinPopup(n),
151
243
  [t]
152
244
  ), m = d(
153
- async (r) => {
245
+ async (n) => {
154
246
  try {
155
- return await t.signinSilent(r);
156
- } catch (a) {
157
- return n({
247
+ return await t.signinSilent(n);
248
+ } catch (c) {
249
+ return o({
158
250
  user: null,
159
251
  isLoading: !1,
160
252
  isAuthenticated: !1,
161
253
  isError: !0,
162
- error: a instanceof Error ? a : new Error("Unknown error during silent signin")
254
+ error: c instanceof Error ? c : new Error("Unknown error during silent signin")
163
255
  }), null;
164
256
  }
165
257
  },
166
258
  [t]
167
- ), A = d(
168
- async (r) => {
259
+ ), h = d(
260
+ async (n) => {
169
261
  try {
170
- await t.signoutRedirect(r);
171
- } catch (a) {
172
- console.error(a);
262
+ await t.signoutRedirect(n);
263
+ } catch (c) {
264
+ console.error(c);
173
265
  }
174
266
  },
175
267
  [t]
176
- ), S = v(
268
+ ), S = U(
177
269
  () => ({
178
270
  state: s,
179
271
  handleSigninCallback: u,
180
- redirectToSignin: i,
272
+ redirectToSignin: a,
181
273
  signinSilent: m,
182
274
  signinPopup: l,
183
- logout: A
275
+ logout: h
184
276
  }),
185
277
  [
186
278
  s,
187
279
  u,
188
- i,
280
+ a,
189
281
  m,
190
282
  l,
191
- A
283
+ h
192
284
  ]
193
285
  );
194
- return /* @__PURE__ */ C(e.Provider, { value: S, children: c });
195
- }, p = (t) => {
196
- const e = E(t);
286
+ return /* @__PURE__ */ A(e.Provider, { value: S, children: r });
287
+ }, C = (t) => {
288
+ const e = k(t);
197
289
  if (!e)
198
290
  throw new Error("useAuthContext must be used within an AuthProvider");
199
291
  return e;
200
- }, R = (t) => {
201
- const { state: e } = p(t);
292
+ }, F = (t) => {
293
+ const { state: e } = C(t);
202
294
  return e;
203
- }, b = (t, e) => {
204
- const { state: c, handleSigninCallback: s } = p(t), n = U(!1);
205
- return h(() => {
206
- n.current || (n.current = !0, s().then(
207
- (o) => new Promise(
208
- (u) => setTimeout(() => u(o), 0)
295
+ }, K = (t, e) => {
296
+ const { state: r, handleSigninCallback: s } = C(t), o = x(!1);
297
+ return f(() => {
298
+ o.current || (o.current = !0, s().then(
299
+ (i) => new Promise(
300
+ (u) => setTimeout(() => u(i), 0)
209
301
  )
210
- ).then((o) => e == null ? void 0 : e(o)));
211
- }, [s]), c;
212
- }, q = (t) => {
213
- const e = x(null);
302
+ ).then((i) => e == null ? void 0 : e(i)));
303
+ }, [s]), r;
304
+ }, X = (t) => {
305
+ const e = I(null);
214
306
  return {
215
307
  AuthContext: e,
216
- AuthProvider: ({ children: i }) => /* @__PURE__ */ C(y, { userManager: t, context: e, children: i }),
217
- useAuthContext: () => p(e),
218
- useAuthState: () => R(e),
219
- useSigninCallback: (i) => b(e, i),
308
+ AuthProvider: ({ children: a }) => /* @__PURE__ */ A(O, { userManager: t, context: e, children: a }),
309
+ useAuthContext: () => C(e),
310
+ useAuthState: () => F(e),
311
+ useSigninCallback: (a) => K(e, a),
220
312
  getAccessToken: async () => {
221
- const i = await t.getUser();
222
- return i ? i.access_token : null;
313
+ const a = await t.getUser();
314
+ return a ? a.access_token : null;
223
315
  }
224
316
  };
225
317
  };
226
318
  export {
227
- z as ImpersonationContextProvider,
228
- J as ROLESAdminInCompany,
229
- _ as ROLESAnsatt,
230
- K as ROLESMAKSAdministrator,
231
- q as createAuthContext,
232
- V as parseUserProfileFCString,
233
- N as useImpersonationCallback,
234
- g as useImpersonationContext
319
+ W as AuthManager,
320
+ V as ImpersonationContextProvider,
321
+ G as ROLESAdminInCompany,
322
+ Q as ROLESAnsatt,
323
+ H as ROLESMAKSAdministrator,
324
+ X as createAuthContext,
325
+ B as parseUserProfileFCString,
326
+ q as useImpersonationCallback,
327
+ b as useImpersonationContext
235
328
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkitektbedriftene/fe-lib",
3
- "version": "6.0.0",
3
+ "version": "6.1.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./oidc": {