Skip to content

Commit edd99f0

Browse files
committed
Fix build issues
1 parent 0f46109 commit edd99f0

16 files changed

Lines changed: 2879 additions & 1351 deletions

packages/express/src/AsgardeoExpressClient.ts

Lines changed: 195 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,202 @@
1616
* under the License.
1717
*/
1818

19-
import {LegacyAsgardeoNodeClient} from '@asgardeo/node';
19+
import {
20+
AsgardeoNodeClient,
21+
AsgardeoRuntimeError,
22+
AuthClientConfig,
23+
AuthURLCallback,
24+
Logger,
25+
SignInOptions,
26+
Storage,
27+
TokenResponse,
28+
User,
29+
} from '@asgardeo/node';
30+
import express from 'express';
31+
import {v4 as generateUUID} from 'uuid';
32+
import {CookieConfig, DEFAULT_LOGIN_PATH, DEFAULT_LOGOUT_PATH} from './constants';
2033
import {AsgardeoExpressConfig} from './models/config';
34+
import {UnauthenticatedCallback} from './models';
35+
import {asgardeoExpressAuth, protectRoute} from './middleware';
36+
import {ExpressClientConfig} from './models/express-client-config';
37+
import {ExpressUtils} from './utils/ExpressUtils';
2138

22-
/**
23-
* Base class for implementing Asgardeo in Express.js based applications.
24-
* This class provides the core functionality for managing user authentication and sessions.
25-
*
26-
* @typeParam T - Configuration type that extends AsgardeoExpressConfig.
27-
*/
28-
abstract class AsgardeoExpressClient<T = AsgardeoExpressConfig> extends LegacyAsgardeoNodeClient<T> {}
39+
class AsgardeoExpressClient<T = AsgardeoExpressConfig> extends AsgardeoNodeClient<T> {
40+
private static _clientConfig: ExpressClientConfig;
41+
private static _instance: AsgardeoExpressClient;
42+
43+
constructor(config: ExpressClientConfig, storage?: Storage) {
44+
const nodeClientConfig = {
45+
...config,
46+
afterSignInUrl: config.appURL + (config.loginPath ?? DEFAULT_LOGIN_PATH),
47+
afterSignOutUrl: config.appURL + (config.logoutPath ?? DEFAULT_LOGOUT_PATH),
48+
} as unknown as AuthClientConfig<T>;
49+
50+
super(nodeClientConfig, storage);
51+
AsgardeoExpressClient._clientConfig = {...config};
52+
}
53+
54+
public static getInstance(config: ExpressClientConfig, storage?: Storage): AsgardeoExpressClient;
55+
public static getInstance(): AsgardeoExpressClient;
56+
public static getInstance(config?: ExpressClientConfig, storage?: Storage): AsgardeoExpressClient {
57+
if (!AsgardeoExpressClient._instance && config) {
58+
AsgardeoExpressClient._instance = new AsgardeoExpressClient(config, storage);
59+
Logger.debug('Initialized AsgardeoExpressClient successfully');
60+
}
61+
62+
if (!AsgardeoExpressClient._instance && !config) {
63+
throw new AsgardeoRuntimeError(
64+
'User configuration is not found',
65+
'EXPRESS-CLIENT-GI1-NF01',
66+
'@asgardeo/express',
67+
'User config has not been passed to initialize AsgardeoExpressClient',
68+
);
69+
}
70+
71+
return AsgardeoExpressClient._instance;
72+
}
73+
74+
public override signIn(
75+
req: express.Request,
76+
res: express.Response,
77+
next: express.NextFunction,
78+
signInConfig?: Record<string, string | boolean>,
79+
): Promise<TokenResponse>;
80+
public override signIn(
81+
authURLCallback: AuthURLCallback,
82+
userId: string,
83+
authorizationCode?: string,
84+
sessionState?: string,
85+
state?: string,
86+
signInConfig?: Record<string, string | boolean>,
87+
): Promise<TokenResponse>;
88+
public override signIn(options?: SignInOptions): Promise<User>;
89+
public override async signIn(
90+
reqOrCallbackOrOptions?: express.Request | AuthURLCallback | SignInOptions,
91+
resOrUserId?: express.Response | string,
92+
nextOrCode?: express.NextFunction | string,
93+
signInConfigOrSessionState?: Record<string, string | boolean> | string,
94+
state?: string,
95+
signInConfig?: Record<string, string | boolean>,
96+
): Promise<TokenResponse | User> {
97+
if (resOrUserId !== undefined && typeof resOrUserId !== 'string') {
98+
return this._expressSignIn(
99+
reqOrCallbackOrOptions as express.Request,
100+
resOrUserId,
101+
nextOrCode as express.NextFunction,
102+
signInConfigOrSessionState as Record<string, string | boolean> | undefined,
103+
);
104+
}
105+
106+
if (typeof reqOrCallbackOrOptions === 'function') {
107+
return super.signIn(
108+
reqOrCallbackOrOptions,
109+
resOrUserId as string,
110+
nextOrCode as string,
111+
signInConfigOrSessionState as string,
112+
state,
113+
signInConfig,
114+
);
115+
}
116+
117+
return super.signIn(reqOrCallbackOrOptions as SignInOptions);
118+
}
119+
120+
private async _expressSignIn(
121+
req: express.Request,
122+
res: express.Response,
123+
next: express.NextFunction,
124+
signInConfig?: Record<string, string | boolean>,
125+
): Promise<TokenResponse> {
126+
if (ExpressUtils.hasErrorInURL(req.originalUrl)) {
127+
return Promise.reject(
128+
new AsgardeoRuntimeError(
129+
'Invalid login request URL',
130+
'EXPRESS-CLIENT-SI-IV01',
131+
'@asgardeo/express',
132+
'Login request contains an error query parameter in the URL',
133+
),
134+
);
135+
}
136+
137+
let userId: string = req.cookies.ASGARDEO_SESSION_ID;
138+
if (!userId) {
139+
userId = generateUUID();
140+
}
141+
142+
const authRedirectCallback: AuthURLCallback = (url: string) => {
143+
if (url) {
144+
Logger.debug('Redirecting to: ' + url);
145+
res.cookie('ASGARDEO_SESSION_ID', userId, {
146+
maxAge: AsgardeoExpressClient._clientConfig.cookieConfig?.maxAge ?? CookieConfig.defaultMaxAge,
147+
httpOnly: AsgardeoExpressClient._clientConfig.cookieConfig?.httpOnly ?? CookieConfig.defaultHttpOnly,
148+
sameSite: AsgardeoExpressClient._clientConfig.cookieConfig?.sameSite ?? CookieConfig.defaultSameSite,
149+
secure: AsgardeoExpressClient._clientConfig.cookieConfig?.secure ?? CookieConfig.defaultSecure,
150+
});
151+
res.redirect(url);
152+
153+
if (typeof next === 'function') {
154+
next();
155+
}
156+
}
157+
};
158+
159+
const authResponse: TokenResponse = await super.signIn(
160+
authRedirectCallback,
161+
userId,
162+
req.query.code as string,
163+
req.query.session_state as string,
164+
req.query.state as string,
165+
signInConfig,
166+
);
167+
168+
if (authResponse.accessToken || authResponse.idToken) {
169+
return authResponse;
170+
}
171+
172+
return {
173+
accessToken: '',
174+
createdAt: 0,
175+
expiresIn: '',
176+
idToken: '',
177+
refreshToken: '',
178+
scope: '',
179+
tokenType: '',
180+
};
181+
}
182+
183+
public static protectRoute(
184+
callback: UnauthenticatedCallback,
185+
): (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void> {
186+
if (!this._instance) {
187+
throw new AsgardeoRuntimeError(
188+
'AsgardeoExpressClient is not instantiated',
189+
'EXPRESS-CLIENT-PR-NF01',
190+
'@asgardeo/express',
191+
'Create an instance of AsgardeoExpressClient before calling this method.',
192+
);
193+
}
194+
195+
return protectRoute(this._instance, callback);
196+
}
197+
198+
public static asgardeoExpressAuth(
199+
onSignIn: (res: express.Response, response: TokenResponse) => void,
200+
onSignOut: (res: express.Response) => void,
201+
onError: (res: express.Response, exception: AsgardeoRuntimeError) => void,
202+
): any {
203+
if (!this._instance) {
204+
throw new AsgardeoRuntimeError(
205+
'AsgardeoExpressClient is not instantiated',
206+
'EXPRESS-CLIENT-AEA-NF01',
207+
'@asgardeo/express',
208+
'Create an instance of AsgardeoExpressClient before calling this method.',
209+
);
210+
}
211+
212+
return asgardeoExpressAuth(this._instance, AsgardeoExpressClient._clientConfig, onSignIn, onSignOut, onError);
213+
}
214+
}
29215

216+
export {AsgardeoExpressClient};
30217
export default AsgardeoExpressClient;

0 commit comments

Comments
 (0)