@hamak/auth 0.5.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.
Files changed (116) hide show
  1. package/README.md +366 -0
  2. package/dist/api/api/auth-service.d.ts +111 -0
  3. package/dist/api/api/auth-service.d.ts.map +1 -0
  4. package/dist/api/api/auth-service.js +5 -0
  5. package/dist/api/api/index.d.ts +2 -0
  6. package/dist/api/api/index.d.ts.map +1 -0
  7. package/dist/api/api/index.js +1 -0
  8. package/dist/api/index.d.ts +10 -0
  9. package/dist/api/index.d.ts.map +1 -0
  10. package/dist/api/index.js +12 -0
  11. package/dist/api/tokens/index.d.ts +2 -0
  12. package/dist/api/tokens/index.d.ts.map +1 -0
  13. package/dist/api/tokens/index.js +1 -0
  14. package/dist/api/tokens/service-tokens.d.ts +26 -0
  15. package/dist/api/tokens/service-tokens.d.ts.map +1 -0
  16. package/dist/api/tokens/service-tokens.js +25 -0
  17. package/dist/api/types/auth-result.d.ts +69 -0
  18. package/dist/api/types/auth-result.d.ts.map +1 -0
  19. package/dist/api/types/auth-result.js +5 -0
  20. package/dist/api/types/config.d.ts +130 -0
  21. package/dist/api/types/config.d.ts.map +1 -0
  22. package/dist/api/types/config.js +5 -0
  23. package/dist/api/types/credentials.d.ts +52 -0
  24. package/dist/api/types/credentials.d.ts.map +1 -0
  25. package/dist/api/types/credentials.js +5 -0
  26. package/dist/api/types/index.d.ts +5 -0
  27. package/dist/api/types/index.d.ts.map +1 -0
  28. package/dist/api/types/index.js +4 -0
  29. package/dist/api/types/user.d.ts +39 -0
  30. package/dist/api/types/user.d.ts.map +1 -0
  31. package/dist/api/types/user.js +5 -0
  32. package/dist/impl/index.d.ts +15 -0
  33. package/dist/impl/index.d.ts.map +1 -0
  34. package/dist/impl/index.js +21 -0
  35. package/dist/impl/plugin/auth-plugin-factory.d.ts +20 -0
  36. package/dist/impl/plugin/auth-plugin-factory.d.ts.map +1 -0
  37. package/dist/impl/plugin/auth-plugin-factory.js +226 -0
  38. package/dist/impl/plugin/index.d.ts +2 -0
  39. package/dist/impl/plugin/index.d.ts.map +1 -0
  40. package/dist/impl/plugin/index.js +1 -0
  41. package/dist/impl/services/AuthService.d.ts +44 -0
  42. package/dist/impl/services/AuthService.d.ts.map +1 -0
  43. package/dist/impl/services/AuthService.js +277 -0
  44. package/dist/impl/services/index.d.ts +2 -0
  45. package/dist/impl/services/index.d.ts.map +1 -0
  46. package/dist/impl/services/index.js +1 -0
  47. package/dist/impl/storage/LocalTokenStorage.d.ts +32 -0
  48. package/dist/impl/storage/LocalTokenStorage.d.ts.map +1 -0
  49. package/dist/impl/storage/LocalTokenStorage.js +148 -0
  50. package/dist/impl/storage/MemoryTokenStorage.d.ts +34 -0
  51. package/dist/impl/storage/MemoryTokenStorage.d.ts.map +1 -0
  52. package/dist/impl/storage/MemoryTokenStorage.js +91 -0
  53. package/dist/impl/storage/SessionTokenStorage.d.ts +33 -0
  54. package/dist/impl/storage/SessionTokenStorage.d.ts.map +1 -0
  55. package/dist/impl/storage/SessionTokenStorage.js +147 -0
  56. package/dist/impl/storage/index.d.ts +10 -0
  57. package/dist/impl/storage/index.d.ts.map +1 -0
  58. package/dist/impl/storage/index.js +26 -0
  59. package/dist/impl/store/auth-reducer.d.ts +135 -0
  60. package/dist/impl/store/auth-reducer.d.ts.map +1 -0
  61. package/dist/impl/store/auth-reducer.js +179 -0
  62. package/dist/impl/store/index.d.ts +2 -0
  63. package/dist/impl/store/index.d.ts.map +1 -0
  64. package/dist/impl/store/index.js +1 -0
  65. package/dist/impl/strategies/KeycloakStrategy.d.ts +42 -0
  66. package/dist/impl/strategies/KeycloakStrategy.d.ts.map +1 -0
  67. package/dist/impl/strategies/KeycloakStrategy.js +237 -0
  68. package/dist/impl/strategies/OAuth2Strategy.d.ts +30 -0
  69. package/dist/impl/strategies/OAuth2Strategy.d.ts.map +1 -0
  70. package/dist/impl/strategies/OAuth2Strategy.js +232 -0
  71. package/dist/impl/strategies/PasswordStrategy.d.ts +25 -0
  72. package/dist/impl/strategies/PasswordStrategy.d.ts.map +1 -0
  73. package/dist/impl/strategies/PasswordStrategy.js +159 -0
  74. package/dist/impl/strategies/StrategyRegistry.d.ts +24 -0
  75. package/dist/impl/strategies/StrategyRegistry.d.ts.map +1 -0
  76. package/dist/impl/strategies/StrategyRegistry.js +70 -0
  77. package/dist/impl/strategies/index.d.ts +5 -0
  78. package/dist/impl/strategies/index.d.ts.map +1 -0
  79. package/dist/impl/strategies/index.js +4 -0
  80. package/dist/impl/utils/index.d.ts +3 -0
  81. package/dist/impl/utils/index.d.ts.map +1 -0
  82. package/dist/impl/utils/index.js +2 -0
  83. package/dist/impl/utils/jwt.d.ts +81 -0
  84. package/dist/impl/utils/jwt.d.ts.map +1 -0
  85. package/dist/impl/utils/jwt.js +103 -0
  86. package/dist/impl/utils/pkce.d.ts +44 -0
  87. package/dist/impl/utils/pkce.d.ts.map +1 -0
  88. package/dist/impl/utils/pkce.js +93 -0
  89. package/dist/index.d.ts +12 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +11 -0
  92. package/dist/spi/guards/AuthGuard.d.ts +108 -0
  93. package/dist/spi/guards/AuthGuard.d.ts.map +1 -0
  94. package/dist/spi/guards/AuthGuard.js +5 -0
  95. package/dist/spi/guards/index.d.ts +2 -0
  96. package/dist/spi/guards/index.d.ts.map +1 -0
  97. package/dist/spi/guards/index.js +1 -0
  98. package/dist/spi/index.d.ts +12 -0
  99. package/dist/spi/index.d.ts.map +1 -0
  100. package/dist/spi/index.js +15 -0
  101. package/dist/spi/storage/ITokenStorage.d.ts +107 -0
  102. package/dist/spi/storage/ITokenStorage.d.ts.map +1 -0
  103. package/dist/spi/storage/ITokenStorage.js +5 -0
  104. package/dist/spi/storage/index.d.ts +2 -0
  105. package/dist/spi/storage/index.d.ts.map +1 -0
  106. package/dist/spi/storage/index.js +1 -0
  107. package/dist/spi/strategies/IAuthStrategy.d.ts +114 -0
  108. package/dist/spi/strategies/IAuthStrategy.d.ts.map +1 -0
  109. package/dist/spi/strategies/IAuthStrategy.js +16 -0
  110. package/dist/spi/strategies/IStrategyRegistry.d.ts +64 -0
  111. package/dist/spi/strategies/IStrategyRegistry.d.ts.map +1 -0
  112. package/dist/spi/strategies/IStrategyRegistry.js +5 -0
  113. package/dist/spi/strategies/index.d.ts +3 -0
  114. package/dist/spi/strategies/index.d.ts.map +1 -0
  115. package/dist/spi/strategies/index.js +2 -0
  116. package/package.json +78 -0
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Session Storage Token Storage Implementation
3
+ * Persists tokens using browser sessionStorage (cleared when tab closes)
4
+ */
5
+ /**
6
+ * Storage keys
7
+ */
8
+ const STORAGE_KEYS = {
9
+ ACCESS_TOKEN: 'accessToken',
10
+ REFRESH_TOKEN: 'refreshToken',
11
+ EXPIRES_AT: 'expiresAt',
12
+ TOKEN_TYPE: 'tokenType',
13
+ SCOPE: 'scope',
14
+ USER: 'user'
15
+ };
16
+ /**
17
+ * Token storage implementation using sessionStorage
18
+ * Tokens are cleared when the browser tab is closed
19
+ */
20
+ export class SessionTokenStorage {
21
+ constructor(config = {}) {
22
+ this.keyPrefix = config.keyPrefix || '@hamak/auth';
23
+ }
24
+ getKey(key) {
25
+ return `${this.keyPrefix}:${key}`;
26
+ }
27
+ getItem(key) {
28
+ try {
29
+ return sessionStorage.getItem(this.getKey(key));
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ setItem(key, value) {
36
+ try {
37
+ sessionStorage.setItem(this.getKey(key), value);
38
+ }
39
+ catch {
40
+ console.warn('Failed to store item in sessionStorage:', key);
41
+ }
42
+ }
43
+ removeItem(key) {
44
+ try {
45
+ sessionStorage.removeItem(this.getKey(key));
46
+ }
47
+ catch {
48
+ // Ignore errors
49
+ }
50
+ }
51
+ getAccessToken() {
52
+ return this.getItem(STORAGE_KEYS.ACCESS_TOKEN);
53
+ }
54
+ setAccessToken(token, expiresAt) {
55
+ this.setItem(STORAGE_KEYS.ACCESS_TOKEN, token);
56
+ if (expiresAt !== undefined) {
57
+ this.setItem(STORAGE_KEYS.EXPIRES_AT, String(expiresAt));
58
+ }
59
+ }
60
+ getRefreshToken() {
61
+ return this.getItem(STORAGE_KEYS.REFRESH_TOKEN);
62
+ }
63
+ setRefreshToken(token) {
64
+ this.setItem(STORAGE_KEYS.REFRESH_TOKEN, token);
65
+ }
66
+ getTokens() {
67
+ const accessToken = this.getAccessToken();
68
+ if (!accessToken) {
69
+ return null;
70
+ }
71
+ const expiresAtStr = this.getItem(STORAGE_KEYS.EXPIRES_AT);
72
+ const scopeStr = this.getItem(STORAGE_KEYS.SCOPE);
73
+ return {
74
+ accessToken,
75
+ refreshToken: this.getRefreshToken() || undefined,
76
+ tokenType: this.getItem(STORAGE_KEYS.TOKEN_TYPE) || 'Bearer',
77
+ expiresAt: expiresAtStr ? parseInt(expiresAtStr, 10) : undefined,
78
+ scope: scopeStr ? JSON.parse(scopeStr) : undefined
79
+ };
80
+ }
81
+ setTokens(tokens) {
82
+ this.setAccessToken(tokens.accessToken, tokens.expiresAt);
83
+ if (tokens.refreshToken) {
84
+ this.setRefreshToken(tokens.refreshToken);
85
+ }
86
+ if (tokens.tokenType) {
87
+ this.setItem(STORAGE_KEYS.TOKEN_TYPE, tokens.tokenType);
88
+ }
89
+ if (tokens.scope) {
90
+ this.setItem(STORAGE_KEYS.SCOPE, JSON.stringify(tokens.scope));
91
+ }
92
+ }
93
+ clearTokens() {
94
+ this.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
95
+ this.removeItem(STORAGE_KEYS.REFRESH_TOKEN);
96
+ this.removeItem(STORAGE_KEYS.EXPIRES_AT);
97
+ this.removeItem(STORAGE_KEYS.TOKEN_TYPE);
98
+ this.removeItem(STORAGE_KEYS.SCOPE);
99
+ }
100
+ isTokenExpired() {
101
+ const accessToken = this.getAccessToken();
102
+ if (!accessToken) {
103
+ return true;
104
+ }
105
+ const expiresAt = this.getTokenExpiry();
106
+ if (!expiresAt) {
107
+ return false;
108
+ }
109
+ return Date.now() >= expiresAt;
110
+ }
111
+ isTokenExpiringSoon(thresholdMs) {
112
+ const expiresAt = this.getTokenExpiry();
113
+ if (!expiresAt) {
114
+ return false;
115
+ }
116
+ return Date.now() + thresholdMs >= expiresAt;
117
+ }
118
+ getTokenExpiry() {
119
+ const expiresAtStr = this.getItem(STORAGE_KEYS.EXPIRES_AT);
120
+ if (!expiresAtStr) {
121
+ return null;
122
+ }
123
+ return parseInt(expiresAtStr, 10);
124
+ }
125
+ getUser() {
126
+ const userStr = this.getItem(STORAGE_KEYS.USER);
127
+ if (!userStr) {
128
+ return null;
129
+ }
130
+ try {
131
+ return JSON.parse(userStr);
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+ setUser(user) {
138
+ this.setItem(STORAGE_KEYS.USER, JSON.stringify(user));
139
+ }
140
+ clearUser() {
141
+ this.removeItem(STORAGE_KEYS.USER);
142
+ }
143
+ clearAll() {
144
+ this.clearTokens();
145
+ this.clearUser();
146
+ }
147
+ }
@@ -0,0 +1,10 @@
1
+ export * from './LocalTokenStorage';
2
+ export * from './SessionTokenStorage';
3
+ export * from './MemoryTokenStorage';
4
+ import type { TokenStorageType } from '../../api';
5
+ import type { ITokenStorage, TokenStorageConfig } from '../../spi';
6
+ /**
7
+ * Factory function to create a token storage based on type
8
+ */
9
+ export declare function createTokenStorage(type: TokenStorageType, config?: TokenStorageConfig): ITokenStorage;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AAErC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAKnE;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,gBAAgB,EACtB,MAAM,CAAC,EAAE,kBAAkB,GAC1B,aAAa,CAgBf"}
@@ -0,0 +1,26 @@
1
+ export * from './LocalTokenStorage';
2
+ export * from './SessionTokenStorage';
3
+ export * from './MemoryTokenStorage';
4
+ import { LocalTokenStorage } from './LocalTokenStorage';
5
+ import { SessionTokenStorage } from './SessionTokenStorage';
6
+ import { MemoryTokenStorage } from './MemoryTokenStorage';
7
+ /**
8
+ * Factory function to create a token storage based on type
9
+ */
10
+ export function createTokenStorage(type, config) {
11
+ switch (type) {
12
+ case 'localStorage':
13
+ return new LocalTokenStorage(config);
14
+ case 'sessionStorage':
15
+ return new SessionTokenStorage(config);
16
+ case 'memory':
17
+ return new MemoryTokenStorage();
18
+ case 'cookie':
19
+ // Cookie storage would require additional implementation
20
+ // Fall back to localStorage for now
21
+ console.warn('Cookie storage not implemented, falling back to localStorage');
22
+ return new LocalTokenStorage(config);
23
+ default:
24
+ return new LocalTokenStorage(config);
25
+ }
26
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Auth Redux Reducer
3
+ * State management for authentication
4
+ */
5
+ import type { AuthError, User } from '../../api';
6
+ /**
7
+ * Auth state shape
8
+ */
9
+ export interface AuthState {
10
+ /** Whether the user is authenticated */
11
+ isAuthenticated: boolean;
12
+ /** The current user */
13
+ user: User | null;
14
+ /** Whether an auth operation is in progress */
15
+ loading: boolean;
16
+ /** The last auth error */
17
+ error: AuthError | null;
18
+ /** Whether the auth service has been initialized */
19
+ initialized: boolean;
20
+ }
21
+ /**
22
+ * Auth action types
23
+ */
24
+ export declare const AUTH_ACTION_TYPES: {
25
+ readonly INIT: "@hamak/auth/INIT";
26
+ readonly INIT_SUCCESS: "@hamak/auth/INIT_SUCCESS";
27
+ readonly INIT_FAILURE: "@hamak/auth/INIT_FAILURE";
28
+ readonly LOGIN_REQUEST: "@hamak/auth/LOGIN_REQUEST";
29
+ readonly LOGIN_SUCCESS: "@hamak/auth/LOGIN_SUCCESS";
30
+ readonly LOGIN_FAILURE: "@hamak/auth/LOGIN_FAILURE";
31
+ readonly LOGOUT: "@hamak/auth/LOGOUT";
32
+ readonly TOKEN_REFRESH: "@hamak/auth/TOKEN_REFRESH";
33
+ readonly TOKEN_REFRESH_SUCCESS: "@hamak/auth/TOKEN_REFRESH_SUCCESS";
34
+ readonly TOKEN_REFRESH_FAILURE: "@hamak/auth/TOKEN_REFRESH_FAILURE";
35
+ readonly SESSION_EXPIRED: "@hamak/auth/SESSION_EXPIRED";
36
+ readonly UPDATE_USER: "@hamak/auth/UPDATE_USER";
37
+ readonly CLEAR_ERROR: "@hamak/auth/CLEAR_ERROR";
38
+ };
39
+ /**
40
+ * Auth action types
41
+ */
42
+ export type AuthActionType = (typeof AUTH_ACTION_TYPES)[keyof typeof AUTH_ACTION_TYPES];
43
+ /**
44
+ * Auth actions
45
+ */
46
+ export type AuthAction = {
47
+ type: typeof AUTH_ACTION_TYPES.INIT;
48
+ } | {
49
+ type: typeof AUTH_ACTION_TYPES.INIT_SUCCESS;
50
+ payload: {
51
+ user: User | null;
52
+ isAuthenticated: boolean;
53
+ };
54
+ } | {
55
+ type: typeof AUTH_ACTION_TYPES.INIT_FAILURE;
56
+ payload: AuthError;
57
+ } | {
58
+ type: typeof AUTH_ACTION_TYPES.LOGIN_REQUEST;
59
+ } | {
60
+ type: typeof AUTH_ACTION_TYPES.LOGIN_SUCCESS;
61
+ payload: {
62
+ user: User;
63
+ };
64
+ } | {
65
+ type: typeof AUTH_ACTION_TYPES.LOGIN_FAILURE;
66
+ payload: AuthError;
67
+ } | {
68
+ type: typeof AUTH_ACTION_TYPES.LOGOUT;
69
+ } | {
70
+ type: typeof AUTH_ACTION_TYPES.TOKEN_REFRESH;
71
+ } | {
72
+ type: typeof AUTH_ACTION_TYPES.TOKEN_REFRESH_SUCCESS;
73
+ payload: {
74
+ user?: User;
75
+ };
76
+ } | {
77
+ type: typeof AUTH_ACTION_TYPES.TOKEN_REFRESH_FAILURE;
78
+ payload: AuthError;
79
+ } | {
80
+ type: typeof AUTH_ACTION_TYPES.SESSION_EXPIRED;
81
+ } | {
82
+ type: typeof AUTH_ACTION_TYPES.UPDATE_USER;
83
+ payload: User;
84
+ } | {
85
+ type: typeof AUTH_ACTION_TYPES.CLEAR_ERROR;
86
+ };
87
+ /**
88
+ * Auth reducer
89
+ */
90
+ export declare function authReducer(state: AuthState | undefined, action: AuthAction): AuthState;
91
+ /**
92
+ * Action creators
93
+ */
94
+ export declare const authActions: {
95
+ init: () => AuthAction;
96
+ initSuccess: (user: User | null, isAuthenticated: boolean) => AuthAction;
97
+ initFailure: (error: AuthError) => AuthAction;
98
+ loginRequest: () => AuthAction;
99
+ loginSuccess: (user: User) => AuthAction;
100
+ loginFailure: (error: AuthError) => AuthAction;
101
+ logout: () => AuthAction;
102
+ tokenRefresh: () => AuthAction;
103
+ tokenRefreshSuccess: (user?: User) => AuthAction;
104
+ tokenRefreshFailure: (error: AuthError) => AuthAction;
105
+ sessionExpired: () => AuthAction;
106
+ updateUser: (user: User) => AuthAction;
107
+ clearError: () => AuthAction;
108
+ };
109
+ /**
110
+ * Selectors
111
+ */
112
+ export declare const authSelectors: {
113
+ selectIsAuthenticated: (state: {
114
+ auth: AuthState;
115
+ }) => boolean;
116
+ selectUser: (state: {
117
+ auth: AuthState;
118
+ }) => User | null;
119
+ selectIsLoading: (state: {
120
+ auth: AuthState;
121
+ }) => boolean;
122
+ selectError: (state: {
123
+ auth: AuthState;
124
+ }) => AuthError | null;
125
+ selectIsInitialized: (state: {
126
+ auth: AuthState;
127
+ }) => boolean;
128
+ selectRoles: (state: {
129
+ auth: AuthState;
130
+ }) => string[];
131
+ selectPermissions: (state: {
132
+ auth: AuthState;
133
+ }) => string[];
134
+ };
135
+ //# sourceMappingURL=auth-reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-reducer.d.ts","sourceRoot":"","sources":["../../../src/impl/store/auth-reducer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Auth Redux Reducer
3
+ * State management for authentication
4
+ */
5
+ /**
6
+ * Initial auth state
7
+ */
8
+ const initialState = {
9
+ isAuthenticated: false,
10
+ user: null,
11
+ loading: false,
12
+ error: null,
13
+ initialized: false
14
+ };
15
+ /**
16
+ * Auth action types
17
+ */
18
+ export const AUTH_ACTION_TYPES = {
19
+ INIT: '@hamak/auth/INIT',
20
+ INIT_SUCCESS: '@hamak/auth/INIT_SUCCESS',
21
+ INIT_FAILURE: '@hamak/auth/INIT_FAILURE',
22
+ LOGIN_REQUEST: '@hamak/auth/LOGIN_REQUEST',
23
+ LOGIN_SUCCESS: '@hamak/auth/LOGIN_SUCCESS',
24
+ LOGIN_FAILURE: '@hamak/auth/LOGIN_FAILURE',
25
+ LOGOUT: '@hamak/auth/LOGOUT',
26
+ TOKEN_REFRESH: '@hamak/auth/TOKEN_REFRESH',
27
+ TOKEN_REFRESH_SUCCESS: '@hamak/auth/TOKEN_REFRESH_SUCCESS',
28
+ TOKEN_REFRESH_FAILURE: '@hamak/auth/TOKEN_REFRESH_FAILURE',
29
+ SESSION_EXPIRED: '@hamak/auth/SESSION_EXPIRED',
30
+ UPDATE_USER: '@hamak/auth/UPDATE_USER',
31
+ CLEAR_ERROR: '@hamak/auth/CLEAR_ERROR'
32
+ };
33
+ /**
34
+ * Auth reducer
35
+ */
36
+ export function authReducer(state = initialState, action) {
37
+ switch (action.type) {
38
+ case AUTH_ACTION_TYPES.INIT:
39
+ return {
40
+ ...state,
41
+ loading: true,
42
+ error: null
43
+ };
44
+ case AUTH_ACTION_TYPES.INIT_SUCCESS:
45
+ return {
46
+ ...state,
47
+ loading: false,
48
+ initialized: true,
49
+ isAuthenticated: action.payload.isAuthenticated,
50
+ user: action.payload.user,
51
+ error: null
52
+ };
53
+ case AUTH_ACTION_TYPES.INIT_FAILURE:
54
+ return {
55
+ ...state,
56
+ loading: false,
57
+ initialized: true,
58
+ isAuthenticated: false,
59
+ user: null,
60
+ error: action.payload
61
+ };
62
+ case AUTH_ACTION_TYPES.LOGIN_REQUEST:
63
+ return {
64
+ ...state,
65
+ loading: true,
66
+ error: null
67
+ };
68
+ case AUTH_ACTION_TYPES.LOGIN_SUCCESS:
69
+ return {
70
+ ...state,
71
+ loading: false,
72
+ isAuthenticated: true,
73
+ user: action.payload.user,
74
+ error: null
75
+ };
76
+ case AUTH_ACTION_TYPES.LOGIN_FAILURE:
77
+ return {
78
+ ...state,
79
+ loading: false,
80
+ isAuthenticated: false,
81
+ user: null,
82
+ error: action.payload
83
+ };
84
+ case AUTH_ACTION_TYPES.LOGOUT:
85
+ return {
86
+ ...initialState,
87
+ initialized: true
88
+ };
89
+ case AUTH_ACTION_TYPES.TOKEN_REFRESH:
90
+ return {
91
+ ...state,
92
+ // Don't set loading for background refresh
93
+ error: null
94
+ };
95
+ case AUTH_ACTION_TYPES.TOKEN_REFRESH_SUCCESS:
96
+ return {
97
+ ...state,
98
+ user: action.payload.user || state.user,
99
+ error: null
100
+ };
101
+ case AUTH_ACTION_TYPES.TOKEN_REFRESH_FAILURE:
102
+ return {
103
+ ...state,
104
+ error: action.payload
105
+ };
106
+ case AUTH_ACTION_TYPES.SESSION_EXPIRED:
107
+ return {
108
+ ...initialState,
109
+ initialized: true,
110
+ error: {
111
+ code: 'token_expired',
112
+ message: 'Your session has expired. Please login again.'
113
+ }
114
+ };
115
+ case AUTH_ACTION_TYPES.UPDATE_USER:
116
+ return {
117
+ ...state,
118
+ user: action.payload
119
+ };
120
+ case AUTH_ACTION_TYPES.CLEAR_ERROR:
121
+ return {
122
+ ...state,
123
+ error: null
124
+ };
125
+ default:
126
+ return state;
127
+ }
128
+ }
129
+ /**
130
+ * Action creators
131
+ */
132
+ export const authActions = {
133
+ init: () => ({ type: AUTH_ACTION_TYPES.INIT }),
134
+ initSuccess: (user, isAuthenticated) => ({
135
+ type: AUTH_ACTION_TYPES.INIT_SUCCESS,
136
+ payload: { user, isAuthenticated }
137
+ }),
138
+ initFailure: (error) => ({
139
+ type: AUTH_ACTION_TYPES.INIT_FAILURE,
140
+ payload: error
141
+ }),
142
+ loginRequest: () => ({ type: AUTH_ACTION_TYPES.LOGIN_REQUEST }),
143
+ loginSuccess: (user) => ({
144
+ type: AUTH_ACTION_TYPES.LOGIN_SUCCESS,
145
+ payload: { user }
146
+ }),
147
+ loginFailure: (error) => ({
148
+ type: AUTH_ACTION_TYPES.LOGIN_FAILURE,
149
+ payload: error
150
+ }),
151
+ logout: () => ({ type: AUTH_ACTION_TYPES.LOGOUT }),
152
+ tokenRefresh: () => ({ type: AUTH_ACTION_TYPES.TOKEN_REFRESH }),
153
+ tokenRefreshSuccess: (user) => ({
154
+ type: AUTH_ACTION_TYPES.TOKEN_REFRESH_SUCCESS,
155
+ payload: { user }
156
+ }),
157
+ tokenRefreshFailure: (error) => ({
158
+ type: AUTH_ACTION_TYPES.TOKEN_REFRESH_FAILURE,
159
+ payload: error
160
+ }),
161
+ sessionExpired: () => ({ type: AUTH_ACTION_TYPES.SESSION_EXPIRED }),
162
+ updateUser: (user) => ({
163
+ type: AUTH_ACTION_TYPES.UPDATE_USER,
164
+ payload: user
165
+ }),
166
+ clearError: () => ({ type: AUTH_ACTION_TYPES.CLEAR_ERROR })
167
+ };
168
+ /**
169
+ * Selectors
170
+ */
171
+ export const authSelectors = {
172
+ selectIsAuthenticated: (state) => state.auth.isAuthenticated,
173
+ selectUser: (state) => state.auth.user,
174
+ selectIsLoading: (state) => state.auth.loading,
175
+ selectError: (state) => state.auth.error,
176
+ selectIsInitialized: (state) => state.auth.initialized,
177
+ selectRoles: (state) => state.auth.user?.roles || [],
178
+ selectPermissions: (state) => state.auth.user?.permissions || []
179
+ };
@@ -0,0 +1,2 @@
1
+ export * from './auth-reducer';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/store/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './auth-reducer';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Keycloak Authentication Strategy
3
+ * Implements authentication with Keycloak identity provider
4
+ */
5
+ import type { AuthResult, KeycloakStrategyConfig, LoginCredentials, OAuthCallbackParams, User } from '../../api';
6
+ import type { IDirectAuthStrategy, IOAuthStrategy, IHttpClient } from '../../spi';
7
+ /**
8
+ * Keycloak authentication strategy
9
+ *
10
+ * Extends OAuth2 strategy with Keycloak-specific features:
11
+ * - Direct grant (password) authentication
12
+ * - Role extraction from JWT tokens
13
+ * - Keycloak realm and resource roles
14
+ * - Proper logout with session invalidation
15
+ */
16
+ export declare class KeycloakStrategy implements IOAuthStrategy, IDirectAuthStrategy {
17
+ private readonly config;
18
+ private readonly httpClient;
19
+ readonly type: "keycloak";
20
+ readonly name: string;
21
+ private readonly oauth2;
22
+ private readonly baseUrl;
23
+ private readonly tokenUrl;
24
+ private readonly logoutUrl;
25
+ constructor(config: KeycloakStrategyConfig, httpClient: IHttpClient, name?: string);
26
+ getAuthorizationUrl(): Promise<string>;
27
+ handleCallback(params: OAuthCallbackParams): Promise<AuthResult>;
28
+ authenticate(credentials: LoginCredentials): Promise<AuthResult>;
29
+ authenticateDirect(username: string, password: string): Promise<AuthResult>;
30
+ refreshToken(refreshToken: string): Promise<AuthResult>;
31
+ logout(accessToken: string): Promise<void>;
32
+ /**
33
+ * Logout with refresh token for complete session invalidation
34
+ */
35
+ logoutWithRefreshToken(refreshToken: string): Promise<void>;
36
+ getStoredState(): string | null;
37
+ clearOAuthState(): void;
38
+ extractUserFromToken(token: string): User | null;
39
+ private extractUserWithRoles;
40
+ private handleKeycloakError;
41
+ }
42
+ //# sourceMappingURL=KeycloakStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeycloakStrategy.d.ts","sourceRoot":"","sources":["../../../src/impl/strategies/KeycloakStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,IAAI,EACL,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAkBlF;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,cAAc,EAAE,mBAAmB;IAUxE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAV7B,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGhB,MAAM,EAAE,sBAAsB,EAC9B,UAAU,EAAE,WAAW,EACxC,IAAI,SAAa;IAyBb,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAItC,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAWhE,YAAY,CAAC,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAuBhE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA+C3E,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmCvD,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBhD;;OAEG;IACG,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjE,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,eAAe,IAAI,IAAI;IAIvB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIhD,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,mBAAmB;CA8D5B"}