cloud-ide-auth 1.0.55 → 1.0.58
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/fesm2022/cloud-ide-auth-cloud-ide-auth-X5at23fU.mjs +886 -0
- package/fesm2022/cloud-ide-auth-cloud-ide-auth-X5at23fU.mjs.map +1 -0
- package/fesm2022/{cloud-ide-auth-reset-password.component-CvXau3Mm.mjs → cloud-ide-auth-reset-password.component-BgSedkfr.mjs} +29 -5
- package/fesm2022/cloud-ide-auth-reset-password.component-BgSedkfr.mjs.map +1 -0
- package/fesm2022/{cloud-ide-auth-sign-in.component-B02aT1tF.mjs → cloud-ide-auth-sign-in.component-DN4aKt8x.mjs} +34 -4
- package/fesm2022/cloud-ide-auth-sign-in.component-DN4aKt8x.mjs.map +1 -0
- package/fesm2022/cloud-ide-auth.mjs +1 -726
- package/fesm2022/cloud-ide-auth.mjs.map +1 -1
- package/index.d.ts +7 -2
- package/package.json +1 -1
- package/fesm2022/cloud-ide-auth-reset-password.component-CvXau3Mm.mjs.map +0 -1
- package/fesm2022/cloud-ide-auth-sign-in.component-B02aT1tF.mjs.map +0 -1
|
@@ -0,0 +1,886 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, Injectable, Component, signal, DestroyRef, input } from '@angular/core';
|
|
4
|
+
import { MLogin, customEncrypt, cidePath, hostManagerRoutesUrl, authRoutesUrl, MResetPassword, MEntitySwitch, generateObjectFromString, MEntityByDomain, generateStringFromObject, coreRoutesUrl, MForgotPassword, validateRequestModal, MReLogin } from 'cloud-ide-lms-model';
|
|
5
|
+
import { BehaviorSubject, of, catchError as catchError$1 } from 'rxjs';
|
|
6
|
+
import { RouterOutlet, Router, ActivatedRoute } from '@angular/router';
|
|
7
|
+
import * as i1 from '@angular/forms';
|
|
8
|
+
import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
9
|
+
import { CommonModule } from '@angular/common';
|
|
10
|
+
import { map, catchError } from 'rxjs/operators';
|
|
11
|
+
import { CideInputComponent, CideEleButtonComponent, CideEleThemeToggleComponent, CideEleFloatingContainerService } from 'cloud-ide-element';
|
|
12
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
13
|
+
import { CideLytSharedWrapperComponent } from 'cloud-ide-layout';
|
|
14
|
+
import { AUTH_SERVICE_TOKEN, APP_STATE_SERVICE_TOKEN } from 'cloud-ide-shared';
|
|
15
|
+
|
|
16
|
+
class CloudIdeAuthService {
|
|
17
|
+
auth_user_mst = new BehaviorSubject({});
|
|
18
|
+
_auth_token = "";
|
|
19
|
+
// Storage keys
|
|
20
|
+
TOKEN_STORAGE_KEY = 'cide_auth_token';
|
|
21
|
+
USER_STORAGE_KEY = 'cide_auth_user';
|
|
22
|
+
// Modern Angular v20 dependency injection pattern
|
|
23
|
+
http = inject(HttpClient);
|
|
24
|
+
constructor() {
|
|
25
|
+
// Modern Angular v20 pattern: Use constructor for initialization only
|
|
26
|
+
this.loadAuthDataFromStorage();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if localStorage is available (browser environment)
|
|
30
|
+
*/
|
|
31
|
+
isLocalStorageAvailable() {
|
|
32
|
+
try {
|
|
33
|
+
return typeof window !== 'undefined' && typeof localStorage !== 'undefined';
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Getter and setter for auth_token with localStorage persistence
|
|
40
|
+
// Single source of truth: localStorage is the authoritative source
|
|
41
|
+
get auth_token() {
|
|
42
|
+
// Always read from localStorage as single source of truth
|
|
43
|
+
if (this.isLocalStorageAvailable()) {
|
|
44
|
+
const storedToken = localStorage.getItem(this.TOKEN_STORAGE_KEY);
|
|
45
|
+
if (storedToken) {
|
|
46
|
+
// Sync in-memory value with localStorage
|
|
47
|
+
this._auth_token = storedToken;
|
|
48
|
+
return storedToken;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return this._auth_token;
|
|
52
|
+
}
|
|
53
|
+
set auth_token(value) {
|
|
54
|
+
// Update in-memory value
|
|
55
|
+
this._auth_token = value;
|
|
56
|
+
// Save to localStorage as single source of truth
|
|
57
|
+
if (!this.isLocalStorageAvailable()) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (value) {
|
|
61
|
+
localStorage.setItem(this.TOKEN_STORAGE_KEY, value);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
localStorage.removeItem(this.TOKEN_STORAGE_KEY);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// View-only token for public APIs
|
|
68
|
+
VIEW_ONLY_TOKEN_STORAGE_KEY = 'cloud_ide_view_only_token';
|
|
69
|
+
_view_only_token = '';
|
|
70
|
+
get view_only_token() {
|
|
71
|
+
// Always read from localStorage as single source of truth
|
|
72
|
+
if (this.isLocalStorageAvailable()) {
|
|
73
|
+
const storedToken = localStorage.getItem(this.VIEW_ONLY_TOKEN_STORAGE_KEY);
|
|
74
|
+
if (storedToken) {
|
|
75
|
+
// Sync in-memory value with localStorage
|
|
76
|
+
this._view_only_token = storedToken;
|
|
77
|
+
return storedToken;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return this._view_only_token;
|
|
81
|
+
}
|
|
82
|
+
set view_only_token(value) {
|
|
83
|
+
// Update in-memory value
|
|
84
|
+
this._view_only_token = value;
|
|
85
|
+
// Save to localStorage as single source of truth
|
|
86
|
+
if (!this.isLocalStorageAvailable()) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (value) {
|
|
90
|
+
localStorage.setItem(this.VIEW_ONLY_TOKEN_STORAGE_KEY, value);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
localStorage.removeItem(this.VIEW_ONLY_TOKEN_STORAGE_KEY);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Load authentication data from localStorage on service initialization
|
|
97
|
+
loadAuthDataFromStorage() {
|
|
98
|
+
if (!this.isLocalStorageAvailable()) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
// Load token
|
|
103
|
+
const storedToken = localStorage.getItem(this.TOKEN_STORAGE_KEY);
|
|
104
|
+
if (storedToken) {
|
|
105
|
+
this._auth_token = storedToken;
|
|
106
|
+
}
|
|
107
|
+
// Load view-only token
|
|
108
|
+
const storedViewOnlyToken = localStorage.getItem(this.VIEW_ONLY_TOKEN_STORAGE_KEY);
|
|
109
|
+
if (storedViewOnlyToken) {
|
|
110
|
+
this._view_only_token = storedViewOnlyToken;
|
|
111
|
+
}
|
|
112
|
+
// Load user data
|
|
113
|
+
const storedUserData = localStorage.getItem(this.USER_STORAGE_KEY);
|
|
114
|
+
if (storedUserData) {
|
|
115
|
+
const userData = JSON.parse(storedUserData);
|
|
116
|
+
this.auth_user_mst.next(userData);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
// Silent error handling for auth data loading
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Store user data in localStorage
|
|
124
|
+
storeUserData(userData) {
|
|
125
|
+
if (userData) {
|
|
126
|
+
this.auth_user_mst.next(userData);
|
|
127
|
+
if (this.isLocalStorageAvailable()) {
|
|
128
|
+
localStorage.setItem(this.USER_STORAGE_KEY, JSON.stringify(userData));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
signIn(body) {
|
|
133
|
+
// Create a copy to avoid mutating the original
|
|
134
|
+
const loginPayload = new MLogin(body);
|
|
135
|
+
if (loginPayload?.user_password) {
|
|
136
|
+
if (loginPayload?.user_password?.length <= 6) {
|
|
137
|
+
// MPIN - no encryption needed for MPIN
|
|
138
|
+
loginPayload.custom_login_method = "mpin";
|
|
139
|
+
loginPayload.mpin_pin = loginPayload?.user_password;
|
|
140
|
+
loginPayload.user_password = "";
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// Password - encrypt before sending
|
|
144
|
+
loginPayload.custom_login_method = "pass";
|
|
145
|
+
loginPayload.user_password = customEncrypt(loginPayload.user_password);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return this.http?.post(cidePath?.join([hostManagerRoutesUrl?.cideSuiteHost, authRoutesUrl?.module, authRoutesUrl?.signIn]), loginPayload);
|
|
149
|
+
}
|
|
150
|
+
forgotPassword(body) {
|
|
151
|
+
return this.http?.post(cidePath?.join([hostManagerRoutesUrl?.cideSuiteHost, authRoutesUrl?.module, authRoutesUrl?.forgotPassword]), body);
|
|
152
|
+
}
|
|
153
|
+
resetPassword(body) {
|
|
154
|
+
const payload = new MResetPassword(body);
|
|
155
|
+
if (payload?.Validate) {
|
|
156
|
+
payload?.Validate();
|
|
157
|
+
}
|
|
158
|
+
// Encrypt password before sending
|
|
159
|
+
if (payload.user_password) {
|
|
160
|
+
payload.user_password = customEncrypt(payload.user_password);
|
|
161
|
+
}
|
|
162
|
+
return this.http?.post(cidePath?.join([hostManagerRoutesUrl?.cideSuiteHost, authRoutesUrl?.module, authRoutesUrl?.resetPassword]), payload);
|
|
163
|
+
}
|
|
164
|
+
// Sign out the user and clear all stored auth data
|
|
165
|
+
signOut() {
|
|
166
|
+
// Clear token and user data from memory
|
|
167
|
+
this._auth_token = "";
|
|
168
|
+
this.auth_user_mst.next({});
|
|
169
|
+
// Clear stored data
|
|
170
|
+
if (this.isLocalStorageAvailable()) {
|
|
171
|
+
localStorage.removeItem(this.TOKEN_STORAGE_KEY);
|
|
172
|
+
localStorage.removeItem(this.USER_STORAGE_KEY);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Check if user is authenticated
|
|
176
|
+
isAuthenticated() {
|
|
177
|
+
return !!this._auth_token;
|
|
178
|
+
}
|
|
179
|
+
// Get current user data
|
|
180
|
+
getCurrentUser() {
|
|
181
|
+
return this.auth_user_mst.getValue();
|
|
182
|
+
}
|
|
183
|
+
// Check if token is expired
|
|
184
|
+
isTokenExpired() {
|
|
185
|
+
try {
|
|
186
|
+
if (!this._auth_token) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
// Extract the payload from the JWT token
|
|
190
|
+
const tokenParts = this._auth_token.split('.');
|
|
191
|
+
if (tokenParts.length !== 3) {
|
|
192
|
+
return true; // Not a valid JWT token
|
|
193
|
+
}
|
|
194
|
+
const payload = JSON.parse(atob(tokenParts[1]));
|
|
195
|
+
// Check expiration time
|
|
196
|
+
const expiration = payload.exp * 1000; // Convert seconds to milliseconds
|
|
197
|
+
return Date.now() >= expiration;
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
return true; // Assume expired if there's an error
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Refresh auth data if needed based on stored data
|
|
204
|
+
refreshAuthState() {
|
|
205
|
+
// If we have a token but no user data, try to load user data
|
|
206
|
+
if (this._auth_token && this.auth_user_mst && Object.keys(this.auth_user_mst.getValue()).length === 0 && this.isLocalStorageAvailable()) {
|
|
207
|
+
const storedUserData = localStorage.getItem(this.USER_STORAGE_KEY);
|
|
208
|
+
if (storedUserData) {
|
|
209
|
+
try {
|
|
210
|
+
const userData = JSON.parse(storedUserData);
|
|
211
|
+
this.auth_user_mst.next(userData);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
// Silent error handling for parsing user data
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// If token is expired, sign out
|
|
219
|
+
if (this.isTokenExpired()) {
|
|
220
|
+
this.signOut();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Switch entity for logged-in user
|
|
225
|
+
* Creates a new auth_logs entry and updates the entity mapping
|
|
226
|
+
* @param entityId - Entity ID to switch to
|
|
227
|
+
* @returns Observable with new token and entity data
|
|
228
|
+
*/
|
|
229
|
+
switchEntity(entityId) {
|
|
230
|
+
const payload = new MEntitySwitch({
|
|
231
|
+
syen_id: entityId
|
|
232
|
+
});
|
|
233
|
+
return this.http?.post(cidePath?.join([hostManagerRoutesUrl?.cideSuiteHost, authRoutesUrl?.module, authRoutesUrl?.switchEntity]), payload);
|
|
234
|
+
}
|
|
235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CloudIdeAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
236
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CloudIdeAuthService, providedIn: 'root' });
|
|
237
|
+
}
|
|
238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CloudIdeAuthService, decorators: [{
|
|
239
|
+
type: Injectable,
|
|
240
|
+
args: [{
|
|
241
|
+
providedIn: 'root'
|
|
242
|
+
}]
|
|
243
|
+
}], ctorParameters: () => [] });
|
|
244
|
+
|
|
245
|
+
class CloudIdeAuthComponent {
|
|
246
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CloudIdeAuthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
247
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: CloudIdeAuthComponent, isStandalone: true, selector: "cide-auth-wrapper", ngImport: i0, template: `
|
|
248
|
+
<router-outlet></router-outlet>
|
|
249
|
+
`, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
250
|
+
}
|
|
251
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CloudIdeAuthComponent, decorators: [{
|
|
252
|
+
type: Component,
|
|
253
|
+
args: [{ selector: 'cide-auth-wrapper', standalone: true, imports: [RouterOutlet], template: `
|
|
254
|
+
<router-outlet></router-outlet>
|
|
255
|
+
` }]
|
|
256
|
+
}] });
|
|
257
|
+
|
|
258
|
+
var cloudIdeAuth_component = /*#__PURE__*/Object.freeze({
|
|
259
|
+
__proto__: null,
|
|
260
|
+
CloudIdeAuthComponent: CloudIdeAuthComponent
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
class EntityDetectionService {
|
|
264
|
+
http = inject(HttpClient);
|
|
265
|
+
/**
|
|
266
|
+
* Extract and normalize domain from current URL
|
|
267
|
+
* @returns Normalized domain string (without www. prefix, lowercase)
|
|
268
|
+
*/
|
|
269
|
+
getDomainFromUrl() {
|
|
270
|
+
if (typeof window === 'undefined') {
|
|
271
|
+
return '';
|
|
272
|
+
}
|
|
273
|
+
const hostname = window.location.hostname;
|
|
274
|
+
// Remove 'www.' prefix if present and convert to lowercase
|
|
275
|
+
return hostname.replace(/^www\./, '').toLowerCase();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Extract entity ID from route parameters (object-to-string format)
|
|
279
|
+
* @param routeParams - Route parameters object (e.g., { query: 'suwrklfs' })
|
|
280
|
+
* @returns Entity ID string or null
|
|
281
|
+
*/
|
|
282
|
+
getEntityIdFromRoute(routeParams) {
|
|
283
|
+
if (!routeParams || !routeParams['query']) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const queryData = generateObjectFromString(routeParams['query']);
|
|
288
|
+
return queryData?.syen_id || null;
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.warn('Failed to decode route parameter:', error);
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Lookup entity ID by domain using API
|
|
297
|
+
* @param domain - Domain string to lookup
|
|
298
|
+
* @returns Observable of entity ID string or null
|
|
299
|
+
*/
|
|
300
|
+
lookupEntityByDomain(domain) {
|
|
301
|
+
if (!domain) {
|
|
302
|
+
return of(null);
|
|
303
|
+
}
|
|
304
|
+
const domainPayload = new MEntityByDomain({ domain });
|
|
305
|
+
const query = generateStringFromObject(domainPayload);
|
|
306
|
+
const url = cidePath.join([
|
|
307
|
+
hostManagerRoutesUrl.cideSuiteHost,
|
|
308
|
+
coreRoutesUrl.module,
|
|
309
|
+
coreRoutesUrl.entityByDomain,
|
|
310
|
+
query
|
|
311
|
+
]);
|
|
312
|
+
return this.http.get(url).pipe(map((response) => {
|
|
313
|
+
if (response?.success && response?.data?._id) {
|
|
314
|
+
return response.data._id;
|
|
315
|
+
}
|
|
316
|
+
return null;
|
|
317
|
+
}), catchError((error) => {
|
|
318
|
+
console.warn('Domain lookup failed:', error);
|
|
319
|
+
return of(null);
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Detect entity ID using priority:
|
|
324
|
+
* 1. Domain lookup (primary)
|
|
325
|
+
* 2. Route parameter (fallback)
|
|
326
|
+
* @param routeParams - Optional route parameters for fallback
|
|
327
|
+
* @returns Observable of entity ID string or null
|
|
328
|
+
*/
|
|
329
|
+
detectEntityId(routeParams) {
|
|
330
|
+
// First, try domain lookup
|
|
331
|
+
const domain = this.getDomainFromUrl();
|
|
332
|
+
if (domain) {
|
|
333
|
+
return this.lookupEntityByDomain(domain).pipe(map((entityId) => {
|
|
334
|
+
// If domain lookup succeeds, return the entity ID
|
|
335
|
+
if (entityId) {
|
|
336
|
+
return entityId;
|
|
337
|
+
}
|
|
338
|
+
// If domain lookup fails, try route parameter fallback
|
|
339
|
+
return this.getEntityIdFromRoute(routeParams);
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
// If no domain, try route parameter fallback
|
|
343
|
+
const routeEntityId = this.getEntityIdFromRoute(routeParams);
|
|
344
|
+
return of(routeEntityId);
|
|
345
|
+
}
|
|
346
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EntityDetectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
347
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EntityDetectionService, providedIn: 'root' });
|
|
348
|
+
}
|
|
349
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EntityDetectionService, decorators: [{
|
|
350
|
+
type: Injectable,
|
|
351
|
+
args: [{
|
|
352
|
+
providedIn: 'root'
|
|
353
|
+
}]
|
|
354
|
+
}] });
|
|
355
|
+
|
|
356
|
+
class CideAuthForgotPasswordComponent {
|
|
357
|
+
forgotPassswordForm;
|
|
358
|
+
erro_message = signal('', ...(ngDevMode ? [{ debugName: "erro_message" }] : []));
|
|
359
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
360
|
+
entityId = signal(null, ...(ngDevMode ? [{ debugName: "entityId" }] : []));
|
|
361
|
+
authService = inject(CloudIdeAuthService);
|
|
362
|
+
router = inject(Router);
|
|
363
|
+
activatedRoute = inject(ActivatedRoute);
|
|
364
|
+
entityDetectionService = inject(EntityDetectionService);
|
|
365
|
+
destroyRef = inject(DestroyRef);
|
|
366
|
+
constructor() {
|
|
367
|
+
this.forgotPassswordForm = new FormGroup({
|
|
368
|
+
custom_forgot_password_method: new FormControl('username'),
|
|
369
|
+
user_username: new FormControl('', [Validators.required, Validators.minLength(8), Validators.maxLength(20)]),
|
|
370
|
+
user_emailid: new FormControl(''),
|
|
371
|
+
user_mobileno: new FormControl(),
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
ngOnInit() {
|
|
375
|
+
// Detect entity ID from domain or route parameter
|
|
376
|
+
const routeParams = this.activatedRoute.snapshot.params;
|
|
377
|
+
this.entityDetectionService.detectEntityId(routeParams).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
378
|
+
next: (entityId) => {
|
|
379
|
+
if (entityId) {
|
|
380
|
+
this.entityId.set(entityId);
|
|
381
|
+
console.log('Entity ID detected:', entityId);
|
|
382
|
+
}
|
|
383
|
+
// Navigate to clean URL (remove :query param) if it exists
|
|
384
|
+
if (routeParams['query']) {
|
|
385
|
+
this.router.navigate(['auth', 'forgot-password'], {
|
|
386
|
+
queryParams: this.activatedRoute.snapshot.queryParams,
|
|
387
|
+
replaceUrl: true
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
error: (error) => {
|
|
392
|
+
console.warn('Entity detection failed:', error);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
onForgotPasssword() {
|
|
397
|
+
// Mark all fields as touched to show validation errors
|
|
398
|
+
this.forgotPassswordForm.markAllAsTouched();
|
|
399
|
+
// Clear previous error messages
|
|
400
|
+
this.erro_message.set('');
|
|
401
|
+
// Check if form has basic Angular validators passed
|
|
402
|
+
if (!this.forgotPassswordForm.valid) {
|
|
403
|
+
const usernameControl = this.forgotPassswordForm.get('user_username');
|
|
404
|
+
if (usernameControl?.errors?.['required']) {
|
|
405
|
+
this.erro_message.set('Username is required');
|
|
406
|
+
}
|
|
407
|
+
else if (usernameControl?.errors?.['minlength']) {
|
|
408
|
+
this.erro_message.set('Username must be at least 8 characters');
|
|
409
|
+
}
|
|
410
|
+
else if (usernameControl?.errors?.['maxlength']) {
|
|
411
|
+
this.erro_message.set('Username must be at most 20 characters');
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
this.erro_message.set('Please fill in all required fields correctly');
|
|
415
|
+
}
|
|
416
|
+
setTimeout(() => {
|
|
417
|
+
this.erro_message.set('');
|
|
418
|
+
}, 3000);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// Create the model and validate using custom validation
|
|
422
|
+
const formValue = {
|
|
423
|
+
...this.forgotPassswordForm.value,
|
|
424
|
+
syen_id: this.entityId() || undefined
|
|
425
|
+
};
|
|
426
|
+
const forgotPasswordPayload = new MForgotPassword(formValue);
|
|
427
|
+
const validate = validateRequestModal(forgotPasswordPayload);
|
|
428
|
+
if (validate !== true) {
|
|
429
|
+
// Custom validation failed
|
|
430
|
+
this.loading.set(false);
|
|
431
|
+
const errorKey = validate.first;
|
|
432
|
+
// Get the error message from errorLogger using the first key
|
|
433
|
+
const errorMessage = validate.errorLogger?.[errorKey] || 'Validation failed. Please check your input.';
|
|
434
|
+
this.erro_message.set(errorMessage);
|
|
435
|
+
console.error('Forgot password validation error:', validate);
|
|
436
|
+
setTimeout(() => {
|
|
437
|
+
this.erro_message.set('');
|
|
438
|
+
}, 3000);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
// All validations passed, make API call
|
|
442
|
+
this.loading.set(true);
|
|
443
|
+
this.authService.forgotPassword(forgotPasswordPayload)?.subscribe({
|
|
444
|
+
next: (response) => {
|
|
445
|
+
this.loading.set(false);
|
|
446
|
+
if (response?.success === true) {
|
|
447
|
+
this.erro_message.set('');
|
|
448
|
+
this.router.navigate(['auth', 'sign-in']);
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
// API returned success: false
|
|
452
|
+
const errorMessage = response?.message || 'Failed to process forgot password request. Please try again.';
|
|
453
|
+
this.erro_message.set(errorMessage);
|
|
454
|
+
console.error('Forgot password API error:', response);
|
|
455
|
+
setTimeout(() => {
|
|
456
|
+
this.erro_message.set('');
|
|
457
|
+
}, 3000);
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
error: (response) => {
|
|
461
|
+
this.loading.set(false);
|
|
462
|
+
const errorMessage = response?.error?.message || 'Failed to process forgot password request. Please try again.';
|
|
463
|
+
this.erro_message.set(errorMessage);
|
|
464
|
+
console.error('Forgot password error:', response);
|
|
465
|
+
setTimeout(() => {
|
|
466
|
+
this.erro_message.set('');
|
|
467
|
+
}, 3000);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideAuthForgotPasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
472
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: CideAuthForgotPasswordComponent, isStandalone: true, selector: "cide-auth-forgot-password", ngImport: i0, template: "<!-- https://play.tailwindcss.com/lfO85drpUy -->\n<!-- Main Div Outer Div-->\n<div class=\"cide-font-poppins tw-flex tw-min-h-screen tw-w-full tw-bg-gray-50 tw-py-3 tw-relative\">\n <!-- Theme Toggle - Top Right Corner -->\n <div class=\"tw-absolute tw-top-4 tw-right-4 tw-z-50\">\n <cide-ele-theme-toggle size=\"small\"></cide-ele-theme-toggle>\n </div>\n <!-- Forrm Wrapper -->\n <div class=\"tw-m-auto tw-w-96 tw-rounded-2xl tw-bg-white tw-py-6 tw-shadow-xl\">\n <!-- Logo Wrapper -->\n <div class=\"tw-m-auto tw-h-32 tw-w-64 tw-text-center\">\n <img src=\"https://console.cloudidesys.com/assets/Cloud%20IDE%20Logo%20Dark.png\" class=\"tw-m-auto tw-h-full\"\n alt=\"Cloud IDE Logo\" />\n </div> <!-- Entity name here -->\n <div class=\"tw-my-2 tw-text-center tw-text-xl tw-font-semibold\">Forgot Password</div>\n <!-- Error Logger -->\n @if (erro_message()) {\n <div class=\"tw-w-full tw-select-none tw-py-1 tw-mx-auto tw-mb-2 tw-max-w-80 tw-text-center tw-text-sm tw-text-red-600 dark:tw-text-red-400\">\n {{erro_message()}}\n </div>\n }\n \n <!-- section for controls -->\n <form [formGroup]=\"forgotPassswordForm\" (ngSubmit)=\"onForgotPasssword()\" novalidate>\n <div class=\"tw-m-auto tw-pb-3 tw-pt-3\">\n <!-- Username -->\n <div class=\"tw-m-auto tw-w-80 tw-mb-4\">\n <cide-ele-input \n id=\"user_username\" \n formControlName=\"user_username\"\n placeholder=\"Enter your username\"\n [required]=\"true\">\n </cide-ele-input>\n @if (forgotPassswordForm.get('user_username')?.invalid && forgotPassswordForm.get('user_username')?.touched) {\n <div class=\"tw-text-xs tw-text-red-600 tw-mt-1\">\n @if (forgotPassswordForm.get('user_username')?.errors?.['required']) {\n Username is required\n } @else if (forgotPassswordForm.get('user_username')?.errors?.['minlength']) {\n Username must be at least 8 characters\n } @else if (forgotPassswordForm.get('user_username')?.errors?.['maxlength']) {\n Username must be at most 20 characters\n }\n </div>\n }\n </div>\n <!-- Forgot Password button -->\n <div class=\"tw-w-80 tw-m-auto tw-mt-3\">\n <button \n type=\"submit\"\n cideEleButton \n id=\"reset_password_link_button\" \n [loading]=\"loading()\" \n [disabled]=\"loading()\">\n Reset Password\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>", styles: [""], dependencies: [{ kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "step", "size"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideEleThemeToggleComponent, selector: "cide-ele-theme-toggle", inputs: ["size"] }] });
|
|
473
|
+
}
|
|
474
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideAuthForgotPasswordComponent, decorators: [{
|
|
475
|
+
type: Component,
|
|
476
|
+
args: [{ selector: 'cide-auth-forgot-password', standalone: true, imports: [CideInputComponent, ReactiveFormsModule, CommonModule, CideEleButtonComponent, CideEleThemeToggleComponent], template: "<!-- https://play.tailwindcss.com/lfO85drpUy -->\n<!-- Main Div Outer Div-->\n<div class=\"cide-font-poppins tw-flex tw-min-h-screen tw-w-full tw-bg-gray-50 tw-py-3 tw-relative\">\n <!-- Theme Toggle - Top Right Corner -->\n <div class=\"tw-absolute tw-top-4 tw-right-4 tw-z-50\">\n <cide-ele-theme-toggle size=\"small\"></cide-ele-theme-toggle>\n </div>\n <!-- Forrm Wrapper -->\n <div class=\"tw-m-auto tw-w-96 tw-rounded-2xl tw-bg-white tw-py-6 tw-shadow-xl\">\n <!-- Logo Wrapper -->\n <div class=\"tw-m-auto tw-h-32 tw-w-64 tw-text-center\">\n <img src=\"https://console.cloudidesys.com/assets/Cloud%20IDE%20Logo%20Dark.png\" class=\"tw-m-auto tw-h-full\"\n alt=\"Cloud IDE Logo\" />\n </div> <!-- Entity name here -->\n <div class=\"tw-my-2 tw-text-center tw-text-xl tw-font-semibold\">Forgot Password</div>\n <!-- Error Logger -->\n @if (erro_message()) {\n <div class=\"tw-w-full tw-select-none tw-py-1 tw-mx-auto tw-mb-2 tw-max-w-80 tw-text-center tw-text-sm tw-text-red-600 dark:tw-text-red-400\">\n {{erro_message()}}\n </div>\n }\n \n <!-- section for controls -->\n <form [formGroup]=\"forgotPassswordForm\" (ngSubmit)=\"onForgotPasssword()\" novalidate>\n <div class=\"tw-m-auto tw-pb-3 tw-pt-3\">\n <!-- Username -->\n <div class=\"tw-m-auto tw-w-80 tw-mb-4\">\n <cide-ele-input \n id=\"user_username\" \n formControlName=\"user_username\"\n placeholder=\"Enter your username\"\n [required]=\"true\">\n </cide-ele-input>\n @if (forgotPassswordForm.get('user_username')?.invalid && forgotPassswordForm.get('user_username')?.touched) {\n <div class=\"tw-text-xs tw-text-red-600 tw-mt-1\">\n @if (forgotPassswordForm.get('user_username')?.errors?.['required']) {\n Username is required\n } @else if (forgotPassswordForm.get('user_username')?.errors?.['minlength']) {\n Username must be at least 8 characters\n } @else if (forgotPassswordForm.get('user_username')?.errors?.['maxlength']) {\n Username must be at most 20 characters\n }\n </div>\n }\n </div>\n <!-- Forgot Password button -->\n <div class=\"tw-w-80 tw-m-auto tw-mt-3\">\n <button \n type=\"submit\"\n cideEleButton \n id=\"reset_password_link_button\" \n [loading]=\"loading()\" \n [disabled]=\"loading()\">\n Reset Password\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>" }]
|
|
477
|
+
}], ctorParameters: () => [] });
|
|
478
|
+
|
|
479
|
+
var forgotPassword_component = /*#__PURE__*/Object.freeze({
|
|
480
|
+
__proto__: null,
|
|
481
|
+
CideAuthForgotPasswordComponent: CideAuthForgotPasswordComponent
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Service to handle re-login functionality when 401 errors occur
|
|
486
|
+
*/
|
|
487
|
+
class ReLoginService {
|
|
488
|
+
http = inject(HttpClient);
|
|
489
|
+
authService = inject(CloudIdeAuthService);
|
|
490
|
+
// Observable to control re-login dialog visibility
|
|
491
|
+
showReLoginSubject = new BehaviorSubject(false);
|
|
492
|
+
showReLogin$ = this.showReLoginSubject.asObservable();
|
|
493
|
+
// Signal for re-login state
|
|
494
|
+
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
495
|
+
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
496
|
+
/**
|
|
497
|
+
* Show re-login dialog
|
|
498
|
+
*/
|
|
499
|
+
showReLogin() {
|
|
500
|
+
// Only show if we have a token (session expired scenario)
|
|
501
|
+
if (this.authService.auth_token) {
|
|
502
|
+
this.showReLoginSubject.next(true);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Hide re-login dialog
|
|
507
|
+
*/
|
|
508
|
+
hideReLogin() {
|
|
509
|
+
this.showReLoginSubject.next(false);
|
|
510
|
+
this.error.set(null);
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Perform re-login with MPIN or password
|
|
514
|
+
*/
|
|
515
|
+
reLogin(payload) {
|
|
516
|
+
this.isLoading.set(true);
|
|
517
|
+
this.error.set(null);
|
|
518
|
+
// Create a copy to avoid mutating the original
|
|
519
|
+
const reLoginPayload = {
|
|
520
|
+
...payload,
|
|
521
|
+
token: this.authService.auth_token
|
|
522
|
+
};
|
|
523
|
+
// Encrypt password if provided (MPIN doesn't need encryption)
|
|
524
|
+
if (reLoginPayload.user_password && reLoginPayload.custom_login_method === 'pass') {
|
|
525
|
+
reLoginPayload.user_password = customEncrypt(reLoginPayload.user_password);
|
|
526
|
+
}
|
|
527
|
+
const url = cidePath.join([
|
|
528
|
+
hostManagerRoutesUrl.cideSuiteHost,
|
|
529
|
+
authRoutesUrl.module,
|
|
530
|
+
authRoutesUrl.createReLoginSession
|
|
531
|
+
]);
|
|
532
|
+
return this.http.post(url, reLoginPayload).pipe(catchError$1((response) => {
|
|
533
|
+
this.isLoading.set(false);
|
|
534
|
+
const errorMessage = response?.error?.message || 'Re-login failed';
|
|
535
|
+
this.error.set(errorMessage);
|
|
536
|
+
return of({
|
|
537
|
+
success: false,
|
|
538
|
+
message: errorMessage
|
|
539
|
+
});
|
|
540
|
+
}));
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Handle successful re-login
|
|
544
|
+
*/
|
|
545
|
+
handleReLoginSuccess(response) {
|
|
546
|
+
if (response.success && response.token) {
|
|
547
|
+
// Update auth token
|
|
548
|
+
this.authService.auth_token = response.token;
|
|
549
|
+
// Update user data if available
|
|
550
|
+
if (response.data) {
|
|
551
|
+
const userData = response.data;
|
|
552
|
+
this.authService.storeUserData(userData);
|
|
553
|
+
}
|
|
554
|
+
// Hide re-login dialog
|
|
555
|
+
this.hideReLogin();
|
|
556
|
+
this.isLoading.set(false);
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
this.error.set(response.message || 'Re-login failed');
|
|
560
|
+
this.isLoading.set(false);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ReLoginService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
564
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ReLoginService, providedIn: 'root' });
|
|
565
|
+
}
|
|
566
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ReLoginService, decorators: [{
|
|
567
|
+
type: Injectable,
|
|
568
|
+
args: [{
|
|
569
|
+
providedIn: 'root'
|
|
570
|
+
}]
|
|
571
|
+
}] });
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Service to manage re-login component in floating container
|
|
575
|
+
*/
|
|
576
|
+
class ReLoginFloatingService {
|
|
577
|
+
containerService = inject(CideEleFloatingContainerService);
|
|
578
|
+
reLoginService = inject(ReLoginService);
|
|
579
|
+
destroyRef = inject(DestroyRef);
|
|
580
|
+
containerId = null;
|
|
581
|
+
constructor() {
|
|
582
|
+
// Register the component when service is initialized
|
|
583
|
+
this.registerReLoginComponent();
|
|
584
|
+
// Subscribe to re-login service to show/hide dialog
|
|
585
|
+
this.reLoginService.showReLogin$
|
|
586
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
587
|
+
.subscribe((shouldShow) => {
|
|
588
|
+
if (shouldShow && !this.containerId) {
|
|
589
|
+
this.show();
|
|
590
|
+
}
|
|
591
|
+
else if (!shouldShow && this.containerId) {
|
|
592
|
+
this.hide();
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Register re-login component with floating container service
|
|
598
|
+
*/
|
|
599
|
+
async registerReLoginComponent() {
|
|
600
|
+
if (this.containerService.isComponentRegistered('re-login')) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
const module = await Promise.resolve().then(function () { return reLogin_component; });
|
|
605
|
+
if (!module.CideAuthReLoginComponent) {
|
|
606
|
+
throw new Error('Component class not found in module');
|
|
607
|
+
}
|
|
608
|
+
this.containerService.registerComponent('re-login', module.CideAuthReLoginComponent);
|
|
609
|
+
}
|
|
610
|
+
catch (error) {
|
|
611
|
+
console.error('Failed to register re-login component:', error);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Show re-login in floating container
|
|
616
|
+
*/
|
|
617
|
+
async show() {
|
|
618
|
+
// Ensure component is registered
|
|
619
|
+
if (!this.containerService.isComponentRegistered('re-login')) {
|
|
620
|
+
await this.registerReLoginComponent();
|
|
621
|
+
}
|
|
622
|
+
const config = {
|
|
623
|
+
id: 're-login-container',
|
|
624
|
+
title: 'Re-Login Required',
|
|
625
|
+
icon: 'lock',
|
|
626
|
+
backdrop: true,
|
|
627
|
+
width: '420px',
|
|
628
|
+
height: 'auto',
|
|
629
|
+
minWidth: '400px',
|
|
630
|
+
minHeight: '200px',
|
|
631
|
+
resizable: false,
|
|
632
|
+
draggable: true,
|
|
633
|
+
closable: false, // Prevent closing - user must re-login
|
|
634
|
+
minimizable: false,
|
|
635
|
+
maximizable: false,
|
|
636
|
+
componentId: 're-login',
|
|
637
|
+
componentConfig: {
|
|
638
|
+
inputs: {},
|
|
639
|
+
outputs: {}
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
this.containerId = this.containerService.show(config);
|
|
643
|
+
return this.containerId;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Hide re-login floating container
|
|
647
|
+
*/
|
|
648
|
+
hide() {
|
|
649
|
+
if (this.containerId) {
|
|
650
|
+
this.containerService.hide(this.containerId);
|
|
651
|
+
this.containerId = null;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ReLoginFloatingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
655
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ReLoginFloatingService, providedIn: 'root' });
|
|
656
|
+
}
|
|
657
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ReLoginFloatingService, decorators: [{
|
|
658
|
+
type: Injectable,
|
|
659
|
+
args: [{
|
|
660
|
+
providedIn: 'root'
|
|
661
|
+
}]
|
|
662
|
+
}], ctorParameters: () => [] });
|
|
663
|
+
|
|
664
|
+
class CideAuthReLoginComponent extends CideLytSharedWrapperComponent {
|
|
665
|
+
shared_wrapper_setup_param = input({
|
|
666
|
+
sypg_page_code: "auth_relogin_dialog"
|
|
667
|
+
}, ...(ngDevMode ? [{ debugName: "shared_wrapper_setup_param" }] : []));
|
|
668
|
+
reLoginService = inject(ReLoginService);
|
|
669
|
+
destroyRef = inject(DestroyRef);
|
|
670
|
+
isLoading = this.reLoginService.isLoading;
|
|
671
|
+
error = this.reLoginService.error;
|
|
672
|
+
reLoginForm = new FormGroup({
|
|
673
|
+
custom_login_method: new FormControl('pass'),
|
|
674
|
+
user_password: new FormControl('')
|
|
675
|
+
});
|
|
676
|
+
constructor() {
|
|
677
|
+
super();
|
|
678
|
+
}
|
|
679
|
+
ngOnInit() {
|
|
680
|
+
super.ngOnInit();
|
|
681
|
+
// Set default login method to password
|
|
682
|
+
this.reLoginForm.patchValue({
|
|
683
|
+
custom_login_method: 'pass'
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
ngOnDestroy() {
|
|
687
|
+
// Cleanup handled by takeUntilDestroyed
|
|
688
|
+
}
|
|
689
|
+
onSubmit() {
|
|
690
|
+
if (this.reLoginForm.valid) {
|
|
691
|
+
const formValue = this.reLoginForm.value;
|
|
692
|
+
const passwordValue = formValue.user_password || '';
|
|
693
|
+
// Auto-detect MPIN vs Password based on length (same as login screen)
|
|
694
|
+
// If length <= 6, treat as MPIN, otherwise as password
|
|
695
|
+
let customLoginMethod = 'pass';
|
|
696
|
+
let userPassword = passwordValue;
|
|
697
|
+
let mpinPin = undefined;
|
|
698
|
+
if (passwordValue && passwordValue.length <= 6) {
|
|
699
|
+
customLoginMethod = 'mpin';
|
|
700
|
+
mpinPin = passwordValue;
|
|
701
|
+
userPassword = undefined;
|
|
702
|
+
}
|
|
703
|
+
const payload = new MReLogin({
|
|
704
|
+
custom_login_method: customLoginMethod,
|
|
705
|
+
user_password: userPassword,
|
|
706
|
+
mpin_pin: mpinPin
|
|
707
|
+
});
|
|
708
|
+
this.reLoginService.reLogin(payload)
|
|
709
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
710
|
+
.subscribe({
|
|
711
|
+
next: (response) => {
|
|
712
|
+
this.reLoginService.handleReLoginSuccess(response);
|
|
713
|
+
},
|
|
714
|
+
error: () => {
|
|
715
|
+
// Error is handled in the service
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideAuthReLoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
721
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: CideAuthReLoginComponent, isStandalone: true, selector: "cide-auth-re-login", inputs: { shared_wrapper_setup_param: { classPropertyName: "shared_wrapper_setup_param", publicName: "shared_wrapper_setup_param", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
|
|
722
|
+
<div class="tw-w-full tw-max-w-md tw-mx-auto tw-p-6">
|
|
723
|
+
<div class="tw-text-center tw-mb-6">
|
|
724
|
+
<h2 class="tw-text-2xl tw-font-semibold tw-text-gray-900 tw-mb-2">Session Expired</h2>
|
|
725
|
+
<p class="tw-text-sm tw-text-gray-600">Please re-authenticate to continue</p>
|
|
726
|
+
</div>
|
|
727
|
+
|
|
728
|
+
@if (error()) {
|
|
729
|
+
<div class="tw-mb-4 tw-p-3 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-lg">
|
|
730
|
+
<p class="tw-text-sm tw-text-red-600">{{ error() }}</p>
|
|
731
|
+
</div>
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
<form [formGroup]="reLoginForm" (ngSubmit)="onSubmit()">
|
|
735
|
+
<div class="tw-space-y-4">
|
|
736
|
+
<!-- Single input field for both password and MPIN -->
|
|
737
|
+
<div>
|
|
738
|
+
<cide-ele-input
|
|
739
|
+
id="user_password_mpin"
|
|
740
|
+
formControlName="user_password"
|
|
741
|
+
type="password"
|
|
742
|
+
placeholder="Enter your password or MPIN"
|
|
743
|
+
[required]="true">
|
|
744
|
+
</cide-ele-input>
|
|
745
|
+
</div>
|
|
746
|
+
|
|
747
|
+
<div class="tw-flex tw-gap-3 tw-pt-4">
|
|
748
|
+
<button
|
|
749
|
+
type="submit"
|
|
750
|
+
cideEleButton
|
|
751
|
+
variant="primary"
|
|
752
|
+
[loading]="isLoading()"
|
|
753
|
+
[disabled]="!reLoginForm.valid || isLoading()"
|
|
754
|
+
class="tw-flex-1">
|
|
755
|
+
Re-Login
|
|
756
|
+
</button>
|
|
757
|
+
</div>
|
|
758
|
+
</div>
|
|
759
|
+
</form>
|
|
760
|
+
</div>
|
|
761
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "step", "size"], outputs: ["ngModelChange"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }] });
|
|
762
|
+
}
|
|
763
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideAuthReLoginComponent, decorators: [{
|
|
764
|
+
type: Component,
|
|
765
|
+
args: [{ selector: 'cide-auth-re-login', standalone: true, imports: [
|
|
766
|
+
CommonModule,
|
|
767
|
+
ReactiveFormsModule,
|
|
768
|
+
CideInputComponent,
|
|
769
|
+
CideEleButtonComponent
|
|
770
|
+
], template: `
|
|
771
|
+
<div class="tw-w-full tw-max-w-md tw-mx-auto tw-p-6">
|
|
772
|
+
<div class="tw-text-center tw-mb-6">
|
|
773
|
+
<h2 class="tw-text-2xl tw-font-semibold tw-text-gray-900 tw-mb-2">Session Expired</h2>
|
|
774
|
+
<p class="tw-text-sm tw-text-gray-600">Please re-authenticate to continue</p>
|
|
775
|
+
</div>
|
|
776
|
+
|
|
777
|
+
@if (error()) {
|
|
778
|
+
<div class="tw-mb-4 tw-p-3 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-lg">
|
|
779
|
+
<p class="tw-text-sm tw-text-red-600">{{ error() }}</p>
|
|
780
|
+
</div>
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
<form [formGroup]="reLoginForm" (ngSubmit)="onSubmit()">
|
|
784
|
+
<div class="tw-space-y-4">
|
|
785
|
+
<!-- Single input field for both password and MPIN -->
|
|
786
|
+
<div>
|
|
787
|
+
<cide-ele-input
|
|
788
|
+
id="user_password_mpin"
|
|
789
|
+
formControlName="user_password"
|
|
790
|
+
type="password"
|
|
791
|
+
placeholder="Enter your password or MPIN"
|
|
792
|
+
[required]="true">
|
|
793
|
+
</cide-ele-input>
|
|
794
|
+
</div>
|
|
795
|
+
|
|
796
|
+
<div class="tw-flex tw-gap-3 tw-pt-4">
|
|
797
|
+
<button
|
|
798
|
+
type="submit"
|
|
799
|
+
cideEleButton
|
|
800
|
+
variant="primary"
|
|
801
|
+
[loading]="isLoading()"
|
|
802
|
+
[disabled]="!reLoginForm.valid || isLoading()"
|
|
803
|
+
class="tw-flex-1">
|
|
804
|
+
Re-Login
|
|
805
|
+
</button>
|
|
806
|
+
</div>
|
|
807
|
+
</div>
|
|
808
|
+
</form>
|
|
809
|
+
</div>
|
|
810
|
+
` }]
|
|
811
|
+
}], ctorParameters: () => [], propDecorators: { shared_wrapper_setup_param: [{ type: i0.Input, args: [{ isSignal: true, alias: "shared_wrapper_setup_param", required: false }] }] } });
|
|
812
|
+
|
|
813
|
+
var reLogin_component = /*#__PURE__*/Object.freeze({
|
|
814
|
+
__proto__: null,
|
|
815
|
+
CideAuthReLoginComponent: CideAuthReLoginComponent
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
const authRoutes = {
|
|
819
|
+
path: "auth", // localhost:4200/auth/sign-in
|
|
820
|
+
loadComponent: () => Promise.resolve().then(function () { return cloudIdeAuth_component; }).then(c => c.CloudIdeAuthComponent),
|
|
821
|
+
children: [
|
|
822
|
+
{
|
|
823
|
+
path: "",
|
|
824
|
+
pathMatch: 'full',
|
|
825
|
+
redirectTo: 'sign-in'
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
path: "sign-in/:query",
|
|
829
|
+
loadComponent: () => import('./cloud-ide-auth-sign-in.component-DN4aKt8x.mjs').then(c => c.CideAuthSignInComponent)
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
path: "sign-in",
|
|
833
|
+
loadComponent: () => import('./cloud-ide-auth-sign-in.component-DN4aKt8x.mjs').then(c => c.CideAuthSignInComponent)
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
path: "forgot-password/:query",
|
|
837
|
+
loadComponent: () => Promise.resolve().then(function () { return forgotPassword_component; }).then(c => c.CideAuthForgotPasswordComponent)
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
path: "forgot-password",
|
|
841
|
+
loadComponent: () => Promise.resolve().then(function () { return forgotPassword_component; }).then(c => c.CideAuthForgotPasswordComponent)
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
path: "reset-password/:rout_token/:query",
|
|
845
|
+
loadComponent: () => import('./cloud-ide-auth-reset-password.component-BgSedkfr.mjs').then(c => c.CideAuthResetPasswordComponent)
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
path: "reset-password/:rout_token",
|
|
849
|
+
loadComponent: () => import('./cloud-ide-auth-reset-password.component-BgSedkfr.mjs').then(c => c.CideAuthResetPasswordComponent)
|
|
850
|
+
}
|
|
851
|
+
]
|
|
852
|
+
};
|
|
853
|
+
|
|
854
|
+
const authGuard = (route, state) => {
|
|
855
|
+
const authService = inject(AUTH_SERVICE_TOKEN);
|
|
856
|
+
const appState = inject(APP_STATE_SERVICE_TOKEN);
|
|
857
|
+
const router = inject(Router);
|
|
858
|
+
// Check if user is authenticated using current state (without refreshing first)
|
|
859
|
+
const isAuthenticated = appState.isUserAuthenticated() && !authService.isTokenExpired();
|
|
860
|
+
// Defer state refresh to next change detection cycle to avoid ExpressionChangedAfterItHasBeenCheckedError
|
|
861
|
+
Promise.resolve().then(() => {
|
|
862
|
+
// Refresh auth state to make sure it's current
|
|
863
|
+
authService.refreshAuthState();
|
|
864
|
+
// Refresh app state from localStorage to ensure synchronization
|
|
865
|
+
appState.refreshFromLocalStorage();
|
|
866
|
+
});
|
|
867
|
+
if (isAuthenticated) {
|
|
868
|
+
return true;
|
|
869
|
+
}
|
|
870
|
+
// Redirect to login page with the intended destination
|
|
871
|
+
// router.navigate(['/auth/sign-in'], {
|
|
872
|
+
// queryParams: { returnUrl: state.url }
|
|
873
|
+
// });
|
|
874
|
+
return false;
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
/*
|
|
878
|
+
* Public API Surface of cloud-ide-auth
|
|
879
|
+
*/
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* Generated bundle index. Do not edit.
|
|
883
|
+
*/
|
|
884
|
+
|
|
885
|
+
export { CloudIdeAuthService as C, EntityDetectionService as E, ReLoginService as R, CloudIdeAuthComponent as a, CideAuthForgotPasswordComponent as b, ReLoginFloatingService as c, CideAuthReLoginComponent as d, authRoutes as e, authGuard as f };
|
|
886
|
+
//# sourceMappingURL=cloud-ide-auth-cloud-ide-auth-X5at23fU.mjs.map
|