|
16 | 16 | * under the License. |
17 | 17 | */ |
18 | 18 |
|
19 | | -import {EmbeddedSignInFlowInitiateResponse} from "./models/embedded-signin-flow"; |
| 19 | +import {AsgardeoAuthClient} from './__legacy__/client'; |
20 | 20 | import {AuthClientConfig} from './__legacy__/models/client-config'; |
21 | | -import {EmbeddedFlowExecuteRequestConfig} from "./models/embedded-flow"; |
22 | | -import {EmbeddedSignInFlowHandleResponse} from "./models/embedded-signin-flow"; |
23 | | -import {EmbeddedSignInFlowStatus} from "./models/embedded-signin-flow"; |
24 | | -import {Crypto} from "./models/crypto"; |
25 | | -import {AsgardeoAuthClient} from "./__legacy__/client"; |
26 | | -import StorageManager from "./StorageManager"; |
27 | | -import executeEmbeddedSignInFlow from "./api/executeEmbeddedSignInFlow"; |
| 21 | +import executeEmbeddedSignInFlow from './api/executeEmbeddedSignInFlow'; |
| 22 | +import initializeEmbeddedSignInFlow from './api/initializeEmbeddedSignInFlow'; |
| 23 | +import {DefaultCacheStore} from './DefaultCacheStore'; |
| 24 | +import {DefaultCrypto} from './DefaultCrypto'; |
| 25 | +import {AgentConfig} from './models/agent'; |
| 26 | +import {AuthCodeResponse} from './models/auth-code-response'; |
28 | 27 | import {AsgardeoClient} from './models/client'; |
29 | 28 | import {Config, SignInOptions, SignOutOptions, SignUpOptions} from './models/config'; |
30 | | -import {EmbeddedFlowExecuteRequestPayload, EmbeddedFlowExecuteResponse} from './models/embedded-flow'; |
| 29 | +import {Crypto} from './models/crypto'; |
| 30 | +import { |
| 31 | + EmbeddedFlowExecuteRequestConfig, |
| 32 | + EmbeddedFlowExecuteRequestPayload, |
| 33 | + EmbeddedFlowExecuteResponse, |
| 34 | +} from './models/embedded-flow'; |
| 35 | +import { |
| 36 | + EmbeddedSignInFlowAuthenticator, |
| 37 | + EmbeddedSignInFlowHandleResponse, |
| 38 | + EmbeddedSignInFlowInitiateResponse, |
| 39 | + EmbeddedSignInFlowStatus, |
| 40 | +} from './models/embedded-signin-flow'; |
31 | 41 | import {AllOrganizationsApiResponse, Organization} from './models/organization'; |
32 | 42 | import {Storage} from './models/store'; |
33 | 43 | import {TokenExchangeRequestConfig, TokenResponse} from './models/token'; |
34 | 44 | import {User, UserProfile} from './models/user'; |
35 | | -import initializeEmbeddedSignInFlow from './api/initializeEmbeddedSignInFlow'; |
36 | | -import {DefaultCacheStore} from './DefaultCacheStore'; |
37 | | -import {DefaultCrypto} from './DefaultCrypto'; |
38 | | - |
39 | | -interface AgentConfig { |
40 | | - agentID: string; |
41 | | - agentSecret: string; |
42 | | -} |
| 45 | +import StorageManager from './StorageManager'; |
43 | 46 |
|
44 | | -export interface AuthCodeResponse { |
45 | | - code: string; |
46 | | - state: string; |
47 | | - session_state: string; |
48 | | -} |
49 | | - |
50 | | -/** |
51 | | - * Base class for implementing Asgardeo clients. |
52 | | - * This class provides the core functionality for managing user authentication and sessions. |
53 | | - * |
54 | | - * @typeParam T - Configuration type that extends Config. |
55 | | - */ |
56 | 47 | class AsgardeoJavaScriptClient<T = Config> implements AsgardeoClient<T> { |
57 | | - |
58 | 48 | private cacheStore: Storage; |
| 49 | + |
59 | 50 | private cryptoUtils: Crypto; |
| 51 | + |
60 | 52 | private auth: AsgardeoAuthClient<T>; |
| 53 | + |
61 | 54 | private storageManager: StorageManager<T>; |
| 55 | + |
62 | 56 | private baseURL: string; |
63 | | - void: void; |
64 | | - |
| 57 | + |
65 | 58 | constructor(config?: AuthClientConfig<T>, cacheStore?: Storage, cryptoUtils?: Crypto) { |
66 | 59 | this.cacheStore = cacheStore ?? new DefaultCacheStore(); |
67 | | - this.cryptoUtils = cryptoUtils ?? new DefaultCrypto(); |
| 60 | + this.cryptoUtils = cryptoUtils ?? new DefaultCrypto(); |
68 | 61 | this.auth = new AsgardeoAuthClient(); |
69 | | - this.auth.initialize(config, this.cacheStore, this.cryptoUtils); |
70 | | - this.storageManager = this.auth.getStorageManager(); |
71 | 62 |
|
72 | | - this.baseURL = config.baseUrl ?? ""; |
| 63 | + if (config) { |
| 64 | + this.auth.initialize(config, this.cacheStore, this.cryptoUtils); |
| 65 | + this.storageManager = this.auth.getStorageManager(); |
| 66 | + } |
| 67 | + |
| 68 | + this.baseURL = config?.baseUrl ?? ''; |
73 | 69 | } |
74 | 70 |
|
75 | | - switchOrganization(organization: Organization, sessionId?: string): Promise<TokenResponse | Response> { |
76 | | - throw new Error("Method not implemented."); |
| 71 | + /* eslint-disable class-methods-use-this, @typescript-eslint/no-unused-vars */ |
| 72 | + switchOrganization(_organization: Organization, _sessionId?: string): Promise<TokenResponse | Response> { |
| 73 | + throw new Error('Method not implemented.'); |
77 | 74 | } |
78 | 75 |
|
79 | | - initialize(config: T, storage?: Storage): Promise<boolean> { |
80 | | - throw new Error("Method not implemented."); |
| 76 | + initialize(_config: T, _storage?: Storage): Promise<boolean> { |
| 77 | + throw new Error('Method not implemented.'); |
81 | 78 | } |
82 | 79 |
|
83 | | - reInitialize(config: Partial<T>): Promise<boolean> { |
84 | | - throw new Error("Method not implemented."); |
| 80 | + reInitialize(_config: Partial<T>): Promise<boolean> { |
| 81 | + throw new Error('Method not implemented.'); |
85 | 82 | } |
86 | 83 |
|
87 | | - getUser(options?: any): Promise<User> { |
88 | | - throw new Error("Method not implemented."); |
| 84 | + getUser(_options?: any): Promise<User> { |
| 85 | + throw new Error('Method not implemented.'); |
89 | 86 | } |
90 | 87 |
|
91 | | - getAllOrganizations(options?: any, sessionId?: string): Promise<AllOrganizationsApiResponse> { |
92 | | - throw new Error("Method not implemented."); |
| 88 | + getAllOrganizations(_options?: any, _sessionId?: string): Promise<AllOrganizationsApiResponse> { |
| 89 | + throw new Error('Method not implemented.'); |
93 | 90 | } |
94 | 91 |
|
95 | | - getMyOrganizations(options?: any, sessionId?: string): Promise<Organization[]> { |
96 | | - throw new Error("Method not implemented."); |
| 92 | + getMyOrganizations(_options?: any, _sessionId?: string): Promise<Organization[]> { |
| 93 | + throw new Error('Method not implemented.'); |
97 | 94 | } |
98 | 95 |
|
99 | | - getCurrentOrganization(sessionId?: string): Promise<Organization | null> { |
100 | | - throw new Error("Method not implemented."); |
| 96 | + getCurrentOrganization(_sessionId?: string): Promise<Organization | null> { |
| 97 | + throw new Error('Method not implemented.'); |
101 | 98 | } |
102 | 99 |
|
103 | | - getUserProfile(options?: any): Promise<UserProfile> { |
104 | | - throw new Error("Method not implemented."); |
| 100 | + getUserProfile(_options?: any): Promise<UserProfile> { |
| 101 | + throw new Error('Method not implemented.'); |
105 | 102 | } |
106 | 103 |
|
107 | 104 | isLoading(): boolean { |
108 | | - throw new Error("Method not implemented."); |
| 105 | + throw new Error('Method not implemented.'); |
109 | 106 | } |
110 | 107 |
|
111 | 108 | isSignedIn(): Promise<boolean> { |
112 | | - throw new Error("Method not implemented."); |
| 109 | + throw new Error('Method not implemented.'); |
113 | 110 | } |
114 | 111 |
|
115 | | - updateUserProfile(payload: any, userId?: string): Promise<User> { |
116 | | - throw new Error("Method not implemented."); |
| 112 | + updateUserProfile(_payload: any, _userId?: string): Promise<User> { |
| 113 | + throw new Error('Method not implemented.'); |
117 | 114 | } |
118 | 115 |
|
119 | 116 | getConfiguration(): T { |
120 | | - throw new Error("Method not implemented."); |
| 117 | + throw new Error('Method not implemented.'); |
121 | 118 | } |
122 | 119 |
|
123 | | - exchangeToken(config: TokenExchangeRequestConfig, sessionId?: string): Promise<TokenResponse | Response> { |
124 | | - throw new Error("Method not implemented."); |
| 120 | + exchangeToken(_config: TokenExchangeRequestConfig, _sessionId?: string): Promise<TokenResponse | Response> { |
| 121 | + throw new Error('Method not implemented.'); |
125 | 122 | } |
126 | 123 |
|
127 | | - signInSilently(options?: SignInOptions): Promise<User | boolean> { |
128 | | - throw new Error("Method not implemented."); |
| 124 | + signInSilently(_options?: SignInOptions): Promise<User | boolean> { |
| 125 | + throw new Error('Method not implemented.'); |
129 | 126 | } |
130 | 127 |
|
131 | | - getAccessToken(sessionId?: string): Promise<string> { |
132 | | - throw new Error("Method not implemented."); |
| 128 | + getAccessToken(_sessionId?: string): Promise<string> { |
| 129 | + throw new Error('Method not implemented.'); |
133 | 130 | } |
134 | 131 |
|
135 | | - clearSession(sessionId?: string): void { |
136 | | - throw new Error("Method not implemented."); |
| 132 | + clearSession(_sessionId?: string): void { |
| 133 | + throw new Error('Method not implemented.'); |
137 | 134 | } |
138 | 135 |
|
139 | | - setSession(sessionData: Record<string, unknown>, sessionId?: string): Promise<void> { |
140 | | - throw new Error("Method not implemented."); |
| 136 | + setSession(_sessionData: Record<string, unknown>, _sessionId?: string): Promise<void> { |
| 137 | + throw new Error('Method not implemented.'); |
141 | 138 | } |
142 | 139 |
|
143 | | - decodeJwtToken<R = Record<string, unknown>>(token: string): Promise<R> { |
144 | | - throw new Error("Method not implemented."); |
| 140 | + decodeJwtToken<R = Record<string, unknown>>(_token: string): Promise<R> { |
| 141 | + throw new Error('Method not implemented.'); |
145 | 142 | } |
146 | 143 |
|
147 | | - signIn(options?: SignInOptions): Promise<User> { |
148 | | - throw new Error("Method not implemented."); |
| 144 | + signIn(_options?: SignInOptions): Promise<User> { |
| 145 | + throw new Error('Method not implemented.'); |
149 | 146 | } |
150 | 147 |
|
151 | | - signOut(options?: SignOutOptions, sessionIdOrAfterSignOut?: string | ((afterSignOutUrl: string) => void), afterSignOut?: (afterSignOutUrl: string) => void): Promise<string> { |
152 | | - throw new Error("Method not implemented."); |
| 148 | + signOut( |
| 149 | + _options?: SignOutOptions, |
| 150 | + _sessionIdOrAfterSignOut?: string | ((afterSignOutUrl: string) => void), |
| 151 | + _afterSignOut?: (afterSignOutUrl: string) => void, |
| 152 | + ): Promise<string> { |
| 153 | + throw new Error('Method not implemented.'); |
153 | 154 | } |
154 | 155 |
|
155 | 156 | signUp(options?: SignUpOptions): Promise<void>; |
156 | 157 |
|
157 | 158 | signUp(payload: EmbeddedFlowExecuteRequestPayload): Promise<EmbeddedFlowExecuteResponse>; |
158 | 159 |
|
159 | | - signUp(optionsOrPayload?: SignUpOptions | EmbeddedFlowExecuteRequestPayload): Promise<void | EmbeddedFlowExecuteResponse> { |
160 | | - throw new Error("Method not implemented."); |
| 160 | + signUp( |
| 161 | + _optionsOrPayload?: SignUpOptions | EmbeddedFlowExecuteRequestPayload, |
| 162 | + ): Promise<void | EmbeddedFlowExecuteResponse> { |
| 163 | + throw new Error('Method not implemented.'); |
161 | 164 | } |
| 165 | + /* eslint-enable class-methods-use-this, @typescript-eslint/no-unused-vars */ |
162 | 166 |
|
163 | | - // Get Agent Token. (AI agent acting on its own) |
164 | 167 | public async getAgentToken(agentConfig: AgentConfig): Promise<TokenResponse> { |
165 | | - const customParam = { |
166 | | - response_mode: "direct", |
| 168 | + const customParam: Record<string, string> = { |
| 169 | + response_mode: 'direct', |
167 | 170 | }; |
168 | 171 |
|
169 | 172 | const authorizeURL: URL = new URL(await this.auth.getSignInUrl(customParam)); |
170 | 173 |
|
171 | 174 | const authorizeResponse: EmbeddedSignInFlowInitiateResponse = await initializeEmbeddedSignInFlow({ |
172 | | - url: `${authorizeURL.origin}${authorizeURL.pathname}`, |
173 | 175 | payload: Object.fromEntries(authorizeURL.searchParams.entries()), |
| 176 | + url: `${authorizeURL.origin}${authorizeURL.pathname}`, |
174 | 177 | }); |
175 | 178 |
|
176 | | - const usernamePasswordAuthenticator = authorizeResponse.nextStep.authenticators.find( |
177 | | - (auth) => auth.authenticator === "Username & Password", |
178 | | - ); |
| 179 | + const authenticatorName: string = agentConfig.authenticatorName ?? AgentConfig.DEFAULT_AUTHENTICATOR_NAME; |
179 | 180 |
|
180 | | - if (!usernamePasswordAuthenticator) { |
181 | | - console.error("Basic authenticator not found among authentication steps."); |
182 | | - return Promise.reject(new Error("Basic authenticator not found among authentication steps.")); |
| 181 | + const targetAuthenticator: EmbeddedSignInFlowAuthenticator | undefined = |
| 182 | + authorizeResponse.nextStep.authenticators.find( |
| 183 | + (auth: EmbeddedSignInFlowAuthenticator) => auth.authenticator === authenticatorName, |
| 184 | + ); |
| 185 | + |
| 186 | + if (!targetAuthenticator) { |
| 187 | + throw new Error(`Authenticator '${authenticatorName}' not found among authentication steps.`); |
183 | 188 | } |
184 | 189 |
|
185 | 190 | const authnRequest: EmbeddedFlowExecuteRequestConfig = { |
186 | 191 | baseUrl: this.baseURL, |
187 | 192 | payload: { |
188 | 193 | flowId: authorizeResponse.flowId, |
189 | 194 | selectedAuthenticator: { |
190 | | - authenticatorId: usernamePasswordAuthenticator.authenticatorId, |
| 195 | + authenticatorId: targetAuthenticator.authenticatorId, |
191 | 196 | params: { |
192 | | - username: agentConfig.agentID, |
193 | 197 | password: agentConfig.agentSecret, |
| 198 | + username: agentConfig.agentID, |
194 | 199 | }, |
195 | 200 | }, |
196 | 201 | }, |
197 | 202 | }; |
198 | 203 |
|
199 | 204 | const authnResponse: EmbeddedSignInFlowHandleResponse = await executeEmbeddedSignInFlow(authnRequest); |
200 | 205 |
|
201 | | - if (authnResponse.flowStatus != EmbeddedSignInFlowStatus.SuccessCompleted) { |
202 | | - console.error("Agent Authentication Failed."); |
203 | | - return Promise.reject(new Error("Agent Authentication Failed.")); |
| 206 | + if (authnResponse.flowStatus !== EmbeddedSignInFlowStatus.SuccessCompleted) { |
| 207 | + throw new Error('Agent authentication failed.'); |
204 | 208 | } |
205 | 209 |
|
206 | | - const tokenResponse = await this.auth.requestAccessToken( |
| 210 | + return this.auth.requestAccessToken( |
207 | 211 | authnResponse.authData['code'], |
208 | 212 | authnResponse.authData['session_state'], |
209 | 213 | authnResponse.authData['state'], |
210 | 214 | ); |
211 | | - |
212 | | - return tokenResponse; |
213 | 215 | } |
214 | 216 |
|
215 | | - // Build Authorize request for the OBO Flow |
216 | 217 | public async getOBOSignInURL(agentConfig: AgentConfig): Promise<string> { |
217 | | - // The authorize request must include requested_actor parameter from the agent configs |
218 | | - const customParam = { |
| 218 | + const customParam: Record<string, string> = { |
219 | 219 | requested_actor: agentConfig.agentID, |
220 | 220 | }; |
221 | 221 |
|
222 | | - // Build authorize URL using AsgardeoAuthClient |
223 | 222 | const authURL: string | undefined = await this.auth.getSignInUrl(customParam); |
224 | 223 |
|
225 | 224 | if (authURL) { |
226 | | - return Promise.resolve(authURL.toString()); |
| 225 | + return authURL.toString(); |
227 | 226 | } |
228 | | - return Promise.reject(new Error("Could not build Authorize URL")); |
| 227 | + |
| 228 | + throw new Error('Could not build Authorize URL'); |
229 | 229 | } |
230 | 230 |
|
231 | | - // Get OBO Token. (AI agent acting on behalf of a user) |
232 | 231 | public async getOBOToken(agentConfig: AgentConfig, authCodeResponse: AuthCodeResponse): Promise<TokenResponse> { |
233 | | - // Get Agent Token |
234 | | - const agentToken = await this.getAgentToken(agentConfig); |
| 232 | + const agentToken: TokenResponse = await this.getAgentToken(agentConfig); |
235 | 233 |
|
236 | | - // Pass Agent Token when requesting access token |
237 | | - const tokenRequestConfig = { |
| 234 | + const tokenRequestConfig: {params: {actor_token: string}} = { |
238 | 235 | params: { |
239 | 236 | actor_token: agentToken.accessToken, |
240 | 237 | }, |
241 | 238 | }; |
242 | 239 |
|
243 | | - // Return OBO Token |
244 | | - return await this.auth.requestAccessToken( |
| 240 | + return this.auth.requestAccessToken( |
245 | 241 | authCodeResponse.code, |
246 | 242 | authCodeResponse.session_state, |
247 | 243 | authCodeResponse.state, |
248 | 244 | undefined, |
249 | | - tokenRequestConfig |
| 245 | + tokenRequestConfig, |
250 | 246 | ); |
251 | 247 | } |
252 | 248 | } |
|
0 commit comments