@rkosafo/cai.components 0.0.26 → 0.0.27

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/index.d.ts CHANGED
@@ -43,4 +43,5 @@ export * from './builders/filters/index.js';
43
43
  export * from './types/index.js';
44
44
  export * from './utils/index.js';
45
45
  import 'iconify-icon';
46
+ export * from './keycloak/index.js';
46
47
  export { YouTube, BaseEditor };
package/dist/index.js CHANGED
@@ -44,4 +44,5 @@ export * from './builders/filters/index.js';
44
44
  export * from './types/index.js';
45
45
  export * from './utils/index.js';
46
46
  import 'iconify-icon';
47
+ export * from './keycloak/index.js';
47
48
  export { YouTube, BaseEditor };
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './keycloakService.js';
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './keycloakService.js';
@@ -0,0 +1,32 @@
1
+ import type { AuthUserInfo, FetchAuthUserInfoFn, KeycloakConfig } from './index.js';
2
+ export declare function createAuthStore(): {
3
+ isLoading: boolean;
4
+ isAuthenticated: boolean;
5
+ accessToken: string;
6
+ idToken: string;
7
+ userInfo: AuthUserInfo | null;
8
+ authError: string;
9
+ userIsFound: boolean;
10
+ };
11
+ export type AuthStoreType = ReturnType<typeof createAuthStore>;
12
+ export declare class KeycloakService {
13
+ private keycloak;
14
+ private initialized;
15
+ private store;
16
+ private fetchUserInfo;
17
+ private onAuthenticated?;
18
+ private onLogout?;
19
+ private onError?;
20
+ constructor(store: AuthStoreType, fetchUserInfo: FetchAuthUserInfoFn, callbacks?: {
21
+ onAuthenticated?: (userInfo: AuthUserInfo) => void;
22
+ onLogout?: () => void;
23
+ onError?: (error: string) => void;
24
+ });
25
+ init(config: KeycloakConfig, initOptions?: any): Promise<void>;
26
+ private setTokenDetails;
27
+ login(): void;
28
+ refreshToken(): Promise<void>;
29
+ logout(): void;
30
+ getKeycloakInstance(): any;
31
+ isInitialized(): boolean;
32
+ }
@@ -0,0 +1,142 @@
1
+ import Keycloak from 'keycloak-js';
2
+ export function createAuthStore() {
3
+ return {
4
+ isLoading: $state(true),
5
+ isAuthenticated: $state(false),
6
+ accessToken: $state(''),
7
+ idToken: $state(''),
8
+ userInfo: $state(null),
9
+ authError: $state(''),
10
+ userIsFound: $state(false)
11
+ };
12
+ }
13
+ export class KeycloakService {
14
+ keycloak = null;
15
+ initialized = false;
16
+ store;
17
+ fetchUserInfo;
18
+ onAuthenticated;
19
+ onLogout;
20
+ onError;
21
+ constructor(store, fetchUserInfo, callbacks) {
22
+ this.store = store;
23
+ this.fetchUserInfo = fetchUserInfo;
24
+ this.onAuthenticated = callbacks?.onAuthenticated;
25
+ this.onLogout = callbacks?.onLogout;
26
+ this.onError = callbacks?.onError;
27
+ }
28
+ async init(config, initOptions = { onLoad: 'login-required', checkLoginIframe: false }) {
29
+ try {
30
+ this.keycloak = new Keycloak(config);
31
+ const authenticated = await this.keycloak.init(initOptions);
32
+ if (authenticated) {
33
+ await this.setTokenDetails(this.keycloak.idTokenParsed);
34
+ }
35
+ else {
36
+ this.setTokenDetails(null);
37
+ }
38
+ this.initialized = true;
39
+ this.store.isLoading = false;
40
+ }
41
+ catch (error) {
42
+ this.initialized = false;
43
+ const errorMessage = error instanceof Error ? error.message : 'Initialization failed';
44
+ this.store.authError = errorMessage;
45
+ this.onError?.(errorMessage);
46
+ this.store.isLoading = false;
47
+ }
48
+ }
49
+ async setTokenDetails(details) {
50
+ if (!details) {
51
+ this.store.isAuthenticated = false;
52
+ this.store.accessToken = '';
53
+ this.store.idToken = '';
54
+ this.store.userInfo = null;
55
+ return;
56
+ }
57
+ try {
58
+ this.store.isAuthenticated = true;
59
+ this.store.accessToken = this.keycloak.token;
60
+ this.store.idToken = this.keycloak.idToken;
61
+ this.store.authError = '';
62
+ // Fetch user info using provided function
63
+ const meRet = await this.fetchUserInfo(this.keycloak.token);
64
+ let extras = {};
65
+ if (meRet.success) {
66
+ extras = meRet.data;
67
+ this.store.userIsFound = true;
68
+ }
69
+ else {
70
+ this.store.authError = meRet.message || 'Failed to fetch user info';
71
+ this.store.userIsFound = meRet.code === 402;
72
+ }
73
+ const userInfo = {
74
+ id: extras.id,
75
+ email: details.email,
76
+ firstName: details.given_name,
77
+ lastName: details.family_name,
78
+ otherNames: '',
79
+ name: details.name,
80
+ username: details.preferred_username,
81
+ initials: details.name
82
+ ?.split(' ')
83
+ .filter((x) => x.length > 1)
84
+ .map((x) => x[0])
85
+ .join('') || '',
86
+ department: extras?.department || '',
87
+ departmentId: extras?.departmentId,
88
+ role: extras?.role,
89
+ roleId: extras?.roleId,
90
+ tags: extras?.tags ?? [],
91
+ permissions: extras?.permissions ?? [],
92
+ type: extras?.type,
93
+ activeDashboardId: extras?.activeDashboardId,
94
+ district: extras?.district,
95
+ phoneNumber: extras?.phoneNumber || '',
96
+ profileImage: extras?.profileImage || '',
97
+ status: extras?.status || ''
98
+ };
99
+ this.store.userInfo = userInfo;
100
+ this.onAuthenticated?.(userInfo);
101
+ }
102
+ catch (error) {
103
+ const errorMessage = error instanceof Error ? error.message : 'Failed to set token details';
104
+ this.store.authError = errorMessage;
105
+ this.onError?.(errorMessage);
106
+ }
107
+ }
108
+ login() {
109
+ if (this.initialized && this.keycloak) {
110
+ this.keycloak.login();
111
+ }
112
+ }
113
+ async refreshToken() {
114
+ if (!this.initialized || !this.keycloak)
115
+ return;
116
+ try {
117
+ const refreshed = await this.keycloak.updateToken(30);
118
+ if (refreshed) {
119
+ await this.setTokenDetails(this.keycloak.idTokenParsed);
120
+ }
121
+ }
122
+ catch (error) {
123
+ const errorMessage = error instanceof Error ? error.message : 'Token refresh failed';
124
+ this.store.authError = errorMessage;
125
+ this.onError?.(errorMessage);
126
+ }
127
+ }
128
+ logout() {
129
+ if (!this.initialized || !this.keycloak)
130
+ return;
131
+ this.keycloak.logout();
132
+ this.store.userInfo = null;
133
+ this.store.isAuthenticated = false;
134
+ this.onLogout?.();
135
+ }
136
+ getKeycloakInstance() {
137
+ return this.keycloak;
138
+ }
139
+ isInitialized() {
140
+ return this.initialized;
141
+ }
142
+ }
@@ -0,0 +1,50 @@
1
+ export interface AuthUserInfo {
2
+ id: string;
3
+ email: string;
4
+ firstName: string;
5
+ lastName: string;
6
+ otherNames: string;
7
+ name: string;
8
+ username: string;
9
+ initials: string;
10
+ profileImage: string;
11
+ role: string;
12
+ roleId: number;
13
+ permissions: string[];
14
+ status: string;
15
+ department?: string;
16
+ departmentId?: number;
17
+ tags?: string[];
18
+ type?: string;
19
+ activeDashboardId?: number;
20
+ district?: string;
21
+ phoneNumber?: string;
22
+ }
23
+ export interface AuthStore {
24
+ isLoading: boolean;
25
+ isAuthenticated: boolean;
26
+ accessToken: string;
27
+ idToken: string;
28
+ userInfo: AuthUserInfo | null;
29
+ authError: string;
30
+ userIsFound: boolean;
31
+ }
32
+ export interface KeycloakConfig {
33
+ url: string;
34
+ realm: string;
35
+ clientId: string;
36
+ }
37
+ export interface FetchAuthUserInfoFn {
38
+ (token?: string): Promise<{
39
+ success: boolean;
40
+ data?: any;
41
+ message?: string;
42
+ code?: number;
43
+ }>;
44
+ }
45
+ export interface FetchAuthDashboardsFn {
46
+ (): Promise<{
47
+ success: boolean;
48
+ data?: any;
49
+ }>;
50
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  export declare function refetchDatatable(params?: TableFilter): void;
2
2
  import { type DatatableProps, type TableFilter } from '../../index.js';
3
- declare const Datatable: import("svelte").Component<DatatableProps<any>, {}, "query" | "read">;
3
+ declare const Datatable: import("svelte").Component<DatatableProps<any>, {}, "read" | "query">;
4
4
  type Datatable = ReturnType<typeof Datatable>;
5
5
  export default Datatable;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rkosafo/cai.components",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",
@@ -58,6 +58,7 @@
58
58
  "date-fns": "^4.1.0",
59
59
  "felte": "^1.3.0",
60
60
  "iconify-icon": "^3.0.0",
61
+ "keycloak-js": "^26.2.0",
61
62
  "lodash": "^4.17.21",
62
63
  "mdsvex": "^0.12.6",
63
64
  "nanoid": "^5.1.5",