@solidstarters/solid-core 1.2.165 → 1.2.168
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/iam.config.d.ts +2 -0
- package/dist/config/iam.config.d.ts.map +1 -1
- package/dist/config/iam.config.js +1 -0
- package/dist/config/iam.config.js.map +1 -1
- package/dist/decorators/error-codes-provider.decorator.d.ts +4 -0
- package/dist/decorators/error-codes-provider.decorator.d.ts.map +1 -0
- package/dist/decorators/error-codes-provider.decorator.js +12 -0
- package/dist/decorators/error-codes-provider.decorator.js.map +1 -0
- package/dist/dtos/post-chatter-message.dto.js.map +1 -1
- package/dist/entities/chatter-message.entity.js.map +1 -1
- package/dist/entities/security-rule.entity.js +0 -1
- package/dist/entities/security-rule.entity.js.map +1 -1
- package/dist/filters/http-exception.filter.d.ts +3 -2
- package/dist/filters/http-exception.filter.d.ts.map +1 -1
- package/dist/filters/http-exception.filter.js +23 -16
- package/dist/filters/http-exception.filter.js.map +1 -1
- package/dist/helpers/error-mapper.service.d.ts +12 -2
- package/dist/helpers/error-mapper.service.d.ts.map +1 -1
- package/dist/helpers/error-mapper.service.js +85 -72
- package/dist/helpers/error-mapper.service.js.map +1 -1
- package/dist/helpers/security.helper.d.ts +4 -2
- package/dist/helpers/security.helper.d.ts.map +1 -1
- package/dist/helpers/security.helper.js +38 -23
- package/dist/helpers/security.helper.js.map +1 -1
- package/dist/helpers/solid-core-error-codes-provider.service.d.ts +7 -0
- package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -0
- package/dist/helpers/solid-core-error-codes-provider.service.js +67 -0
- package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -0
- package/dist/helpers/solid-registry.d.ts +5 -1
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js +16 -0
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +16 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/repository/security-rule.repository.js +2 -2
- package/dist/repository/security-rule.repository.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +2 -2
- package/dist/services/authentication.service.js +5 -4
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/model-metadata.service.js +1 -1
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +2 -1
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/solid-introspect.service.d.ts +1 -0
- package/dist/services/solid-introspect.service.d.ts.map +1 -1
- package/dist/services/solid-introspect.service.js +14 -0
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +2 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config/iam.config.ts +1 -0
- package/src/decorators/error-codes-provider.decorator.ts +9 -0
- package/src/dtos/post-chatter-message.dto.ts +1 -1
- package/src/entities/chatter-message.entity.ts +3 -3
- package/src/entities/security-rule.entity.ts +1 -1
- package/src/filters/http-exception.filter.ts +48 -23
- package/src/helpers/error-mapper.service.ts +117 -176
- package/src/helpers/security.helper.ts +95 -30
- package/src/helpers/solid-core-error-codes-provider.service.ts +63 -0
- package/src/helpers/solid-registry.ts +20 -1
- package/src/index.ts +1 -0
- package/src/interfaces.ts +36 -0
- package/src/repository/security-rule.repository.ts +2 -2
- package/src/seeders/seed-data/solid-core-metadata.json +2 -2
- package/src/services/authentication.service.ts +6 -6
- package/src/services/chatter-message.service.ts +373 -374
- package/src/services/model-metadata.service.ts +1 -1
- package/src/services/setting.service.ts +2 -1
- package/src/services/solid-introspect.service.ts +22 -0
- package/src/solid-core.module.ts +2 -0
|
@@ -1,38 +1,74 @@
|
|
|
1
|
+
import { HelmetOptions } from "helmet";
|
|
1
2
|
import { Environment } from "src/decorators/disallow-in-production.decorator";
|
|
2
|
-
import { HelmetOptions } from "helmet";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Default security headers for SolidX apps.
|
|
6
|
+
* - HSTS only in prod over HTTPS
|
|
7
|
+
* - CSP with frame-ancestors 'none' (prevents clickjacking)
|
|
8
|
+
* - X-Frame-Options: DENY (legacy fallback)
|
|
9
|
+
* - No X-XSS-Protection (deprecated)
|
|
10
|
+
*/
|
|
4
11
|
export function buildDefaultSecurityHeaderOptions(): Readonly<HelmetOptions> {
|
|
5
|
-
|
|
6
|
-
|
|
12
|
+
const isProd = process.env.ENV === Environment.Production;
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
// Modern CSP. Add more directives as your app needs (script-src, connect-src, etc.)
|
|
16
|
+
contentSecurityPolicy: {
|
|
17
|
+
useDefaults: true,
|
|
18
|
+
directives: {
|
|
19
|
+
// sensible secure defaults
|
|
20
|
+
// "default-src": ["'self'"],
|
|
21
|
+
// "base-uri": ["'self'"],
|
|
22
|
+
// "object-src": ["'none'"],
|
|
23
|
+
// "form-action": ["'self'"],
|
|
24
|
+
|
|
25
|
+
// clickjacking defense (modern)
|
|
26
|
+
"frame-ancestors": ["'none'"],
|
|
27
|
+
|
|
28
|
+
// add/adjust as needed for your app:
|
|
29
|
+
// "script-src": ["'self'"], // add hashes/nonces/CSPRO if needed
|
|
30
|
+
// "style-src": ["'self'", "'unsafe-inline'"],
|
|
31
|
+
// "img-src": ["'self'", "data:"],
|
|
32
|
+
// "connect-src": ["'self'", "https://api.example.com"],
|
|
33
|
+
// "frame-src": ["'none'"], // iframes you intentionally allow
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// Legacy clickjacking defense (kept for older UAs)
|
|
39
|
+
frameguard: { action: "deny" },
|
|
40
|
+
|
|
41
|
+
// Referrer/cross-origin policies
|
|
42
|
+
referrerPolicy: { policy: "strict-origin-when-cross-origin" },
|
|
7
43
|
crossOriginEmbedderPolicy: false,
|
|
8
|
-
crossOriginResourcePolicy: { policy:
|
|
9
|
-
|
|
10
|
-
// HSTS
|
|
11
|
-
hsts:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
44
|
+
crossOriginResourcePolicy: { policy: "same-site" },
|
|
45
|
+
|
|
46
|
+
// HSTS only when you’re on HTTPS in production
|
|
47
|
+
hsts: isProd
|
|
48
|
+
? { maxAge: 31536000, includeSubDomains: true, preload: true }
|
|
49
|
+
: false,
|
|
50
|
+
};
|
|
16
51
|
}
|
|
17
52
|
|
|
18
|
-
|
|
19
|
-
type DirectiveConfig = 'self' | 'none' | Source[];
|
|
53
|
+
/* ---------------- Permissions-Policy (formerly Feature-Policy) ---------------- */
|
|
20
54
|
|
|
55
|
+
type Source = "self" | "none" | string;
|
|
56
|
+
type DirectiveConfig = "self" | "none" | Source[];
|
|
21
57
|
export type PermissionsPolicyConfig = Record<string, DirectiveConfig>;
|
|
22
58
|
|
|
23
59
|
export const DEFAULT_PERMISSIONS_POLICY: PermissionsPolicyConfig = {
|
|
24
|
-
camera:
|
|
25
|
-
microphone:
|
|
26
|
-
geolocation:
|
|
27
|
-
fullscreen:
|
|
28
|
-
payment:
|
|
29
|
-
accelerometer:
|
|
30
|
-
autoplay:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
gyroscope:
|
|
34
|
-
magnetometer:
|
|
35
|
-
usb:
|
|
60
|
+
camera: "none",
|
|
61
|
+
microphone: "none",
|
|
62
|
+
geolocation: "none",
|
|
63
|
+
fullscreen: "self",
|
|
64
|
+
payment: "none",
|
|
65
|
+
accelerometer: "none",
|
|
66
|
+
autoplay: "none",
|
|
67
|
+
"clipboard-read": "none",
|
|
68
|
+
"clipboard-write": "none",
|
|
69
|
+
gyroscope: "none",
|
|
70
|
+
magnetometer: "none",
|
|
71
|
+
usb: "none",
|
|
36
72
|
};
|
|
37
73
|
|
|
38
74
|
export function buildPermissionsPolicyHeader(
|
|
@@ -41,13 +77,42 @@ export function buildPermissionsPolicyHeader(
|
|
|
41
77
|
const merged: PermissionsPolicyConfig = { ...DEFAULT_PERMISSIONS_POLICY, ...overrides };
|
|
42
78
|
return Object.entries(merged)
|
|
43
79
|
.map(([feature, value]) => `${feature}=${serializeValue(value)}`)
|
|
44
|
-
.join(
|
|
80
|
+
.join(", ");
|
|
45
81
|
}
|
|
46
82
|
|
|
47
83
|
function serializeValue(v: DirectiveConfig): string {
|
|
48
|
-
if (v ===
|
|
49
|
-
if (v ===
|
|
50
|
-
|
|
51
|
-
const parts = v.map(src => (src === 'self' ? 'self' : src)).join(' ');
|
|
84
|
+
if (v === "none") return "()";
|
|
85
|
+
if (v === "self") return "(self)";
|
|
86
|
+
const parts = v.map((src) => (src === "self" ? "self" : src)).join(" ");
|
|
52
87
|
return `(${parts})`;
|
|
53
88
|
}
|
|
89
|
+
|
|
90
|
+
/* ---------------- Cache-Control helpers ---------------- */
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Default: no-store for HTML/API responses unless you have a reason to cache.
|
|
94
|
+
* Attach as a global middleware or on selected routes.
|
|
95
|
+
*/
|
|
96
|
+
export const DEFAULT_CACHE_CONTROL =
|
|
97
|
+
"no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0, s-maxage=0";
|
|
98
|
+
|
|
99
|
+
export function setDefaultCacheControl() {
|
|
100
|
+
return function cacheControlMiddleware(
|
|
101
|
+
_req: import("express").Request,
|
|
102
|
+
_res: import("express").Response,
|
|
103
|
+
next: import("express").NextFunction
|
|
104
|
+
) {
|
|
105
|
+
_res.setHeader("Cache-Control", DEFAULT_CACHE_CONTROL);
|
|
106
|
+
next();
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* ---------------- Example Express wiring ---------------- */
|
|
111
|
+
// import express from "express";
|
|
112
|
+
// const app = express();
|
|
113
|
+
// app.use(helmet(buildDefaultSecurityHeaderOptions()));
|
|
114
|
+
// app.use((req, res, next) => {
|
|
115
|
+
// res.setHeader("Permissions-Policy", buildPermissionsPolicyHeader());
|
|
116
|
+
// next();
|
|
117
|
+
// });
|
|
118
|
+
// app.use(setDefaultCacheControl());
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/common/errors/providers/solidcore-error-code.provider.ts
|
|
2
|
+
import { Injectable } from '@nestjs/common';
|
|
3
|
+
import { ErrorCodeProvider } from 'src/decorators/error-codes-provider.decorator';
|
|
4
|
+
import { ErrorMeta, ErrorRule, IErrorCodeProvider } from 'src/interfaces';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@ErrorCodeProvider()
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class SolidCoreErrorCodesProvider implements IErrorCodeProvider {
|
|
10
|
+
name(): string {
|
|
11
|
+
return 'SolidCoreErrorCodeProvider';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
rules(): ReadonlyArray<ErrorRule> {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
code: 'solidx-mcp-server-unavailable',
|
|
18
|
+
priority: 100, // run early
|
|
19
|
+
match: (txt) =>
|
|
20
|
+
txt.includes('all connection attempts failed') &&
|
|
21
|
+
txt.includes('unhandled errors in a taskgroup (1 sub-exception)'),
|
|
22
|
+
meta: {
|
|
23
|
+
message: 'SolidX MCP server is unreachable. Please verify the MCP endpoint.',
|
|
24
|
+
httpStatus: 503,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
code: 'db-duplicate-key',
|
|
29
|
+
priority: 90,
|
|
30
|
+
match: (txt) => txt.includes('unique constraint') || txt.includes('duplicate key'),
|
|
31
|
+
meta: {
|
|
32
|
+
message: 'Duplicate key violation. A record with these values already exists.',
|
|
33
|
+
httpStatus: 409,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
code: 'db-foreign-key-error',
|
|
38
|
+
priority: 90,
|
|
39
|
+
match: (txt) => txt.includes('violates foreign key'),
|
|
40
|
+
meta: {
|
|
41
|
+
message:
|
|
42
|
+
'Foreign key constraint prevents this operation due to related records.',
|
|
43
|
+
httpStatus: 409,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
code: 'unknown-error',
|
|
48
|
+
priority: -1, // last resort
|
|
49
|
+
match: (_txt) => true, // fallback catch-all
|
|
50
|
+
meta: {
|
|
51
|
+
message: 'An unexpected error occurred.',
|
|
52
|
+
httpStatus: 500,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Optional explicit meta resolution (if you want)
|
|
59
|
+
resolve(code: string): ErrorMeta | undefined {
|
|
60
|
+
const rule = this.rules().find((r) => r.code === code);
|
|
61
|
+
return rule?.meta;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -5,7 +5,7 @@ import { CommonEntity } from 'src/entities/common.entity';
|
|
|
5
5
|
import { Locale } from 'src/entities/locale.entity';
|
|
6
6
|
import { SecurityRule } from 'src/entities/security-rule.entity';
|
|
7
7
|
import { IScheduledJob } from 'src/services/scheduled-jobs/scheduled-job.interface';
|
|
8
|
-
import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, ISelectionProvider, ISelectionProviderContext } from "../interfaces";
|
|
8
|
+
import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, IErrorCodeProvider, ISelectionProvider, ISelectionProviderContext } from "../interfaces";
|
|
9
9
|
|
|
10
10
|
type ControllerMetadata = {
|
|
11
11
|
name: string;
|
|
@@ -67,6 +67,12 @@ export class SolidRegistry {
|
|
|
67
67
|
private dashboardQuestionDataProviders: Set<InstanceWrapper> = new Set();
|
|
68
68
|
private mailProviders: Set<InstanceWrapper> = new Set();
|
|
69
69
|
private whatsappProviders: Set<InstanceWrapper> = new Set();
|
|
70
|
+
private errorCodeProviders: Set<InstanceWrapper> = new Set();
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
registerErrorCodeProvider(errorCodeProvider: InstanceWrapper): void {
|
|
74
|
+
this.errorCodeProviders.add(errorCodeProvider);
|
|
75
|
+
}
|
|
70
76
|
|
|
71
77
|
registerWhatsappProvider(whatsappProvider: InstanceWrapper): void {
|
|
72
78
|
this.whatsappProviders.add(whatsappProvider);
|
|
@@ -162,6 +168,19 @@ export class SolidRegistry {
|
|
|
162
168
|
}
|
|
163
169
|
}
|
|
164
170
|
|
|
171
|
+
getErrorCodeProviders(): Array<InstanceWrapper> {
|
|
172
|
+
return Array.from(this.errorCodeProviders);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
getErrorCodeProviderInstance(name: string): IErrorCodeProvider | undefined {
|
|
176
|
+
const providers = this.getErrorCodeProviders();
|
|
177
|
+
for (let i = 0; i < providers.length; i++) {
|
|
178
|
+
const p = providers[i];
|
|
179
|
+
if (p.instance?.name?.() === name) return p.instance as IErrorCodeProvider;
|
|
180
|
+
}
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
|
|
165
184
|
getDashboardQuestionDataProviders(): Array<InstanceWrapper> {
|
|
166
185
|
return Array.from(this.dashboardQuestionDataProviders)
|
|
167
186
|
}
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './decorators/protocol.decorator'
|
|
|
19
19
|
export * from './decorators/public.decorator'
|
|
20
20
|
export * from './decorators/roles.decorator'
|
|
21
21
|
export * from './decorators/selection-provider.decorator'
|
|
22
|
+
export * from './decorators/error-codes-provider.decorator'
|
|
22
23
|
export * from './decorators/solid-database-module.decorator'
|
|
23
24
|
export * from './decorators/solid-service.decorator'
|
|
24
25
|
export * from './decorators/mail-provider.decorator'
|
package/src/interfaces.ts
CHANGED
|
@@ -238,3 +238,39 @@ export interface QueuesModuleOptions {
|
|
|
238
238
|
export type MediaWithFullUrl = Media & {
|
|
239
239
|
_full_url: string;
|
|
240
240
|
};
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
export type ErrorCode = string;
|
|
244
|
+
|
|
245
|
+
export type ErrorMeta = {
|
|
246
|
+
message: string;
|
|
247
|
+
httpStatus?: number;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
export type ErrorRule = {
|
|
251
|
+
/** Canonical error code. Keep them kebab-case for consistency. */
|
|
252
|
+
code: ErrorCode;
|
|
253
|
+
/** Higher runs earlier. Defaults to 0 if not provided. */
|
|
254
|
+
priority?: number;
|
|
255
|
+
/** Return true if this rule matches the combined error text. */
|
|
256
|
+
match: (combinedErrorText: string) => boolean;
|
|
257
|
+
/** Display + HTTP mapping for this code. */
|
|
258
|
+
meta: ErrorMeta;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export interface IErrorCodeProvider {
|
|
262
|
+
/** Used for registry identity & logs */
|
|
263
|
+
name(): string;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Return all rules this provider contributes.
|
|
267
|
+
* These will be merged with other providers’ rules, then sorted by priority.
|
|
268
|
+
*/
|
|
269
|
+
rules(): ReadonlyArray<ErrorRule>;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Optional fallback meta for codes this provider owns (when called by getMessage/getHttpStatus).
|
|
273
|
+
* If omitted, the ErrorMapperService will rely on the rule.meta of the first matching rule.
|
|
274
|
+
*/
|
|
275
|
+
resolve?(code: ErrorCode): ErrorMeta | undefined;
|
|
276
|
+
}
|
|
@@ -91,7 +91,7 @@ export class SecurityRuleRepository extends Repository<SecurityRule> {
|
|
|
91
91
|
async upsertWithDto(createDto: CreateSecurityRuleDto) {
|
|
92
92
|
// Populate the role from roleId or roleUserKey
|
|
93
93
|
const roleRepository = this.dataSource.getRepository(RoleMetadata);
|
|
94
|
-
if (
|
|
94
|
+
if (createDto.roleId) {
|
|
95
95
|
const role = await roleRepository.findOne({
|
|
96
96
|
where: {
|
|
97
97
|
id: createDto.roleId,
|
|
@@ -111,7 +111,7 @@ export class SecurityRuleRepository extends Repository<SecurityRule> {
|
|
|
111
111
|
|
|
112
112
|
// Populate the model from modelMetadataId or modelMetadataUserKey
|
|
113
113
|
const modelMetadataRepository = this.dataSource.getRepository(ModelMetadata);
|
|
114
|
-
if (
|
|
114
|
+
if (createDto.modelMetadataId) {
|
|
115
115
|
const modelMetadata = await modelMetadataRepository.findOne({
|
|
116
116
|
where: {
|
|
117
117
|
id: createDto.modelMetadataId,
|
|
@@ -196,7 +196,7 @@ export class AuthenticationService {
|
|
|
196
196
|
|
|
197
197
|
private async populateForSignup<T extends User>(user: T, signUpDto: SignUpDto, isUserActive: boolean = true, onForcePasswordChange?: boolean) {
|
|
198
198
|
// const user = new User();
|
|
199
|
-
|
|
199
|
+
let autoGeneratedPwdPermission = await this.settingService.getConfigValue('iamAutoGeneratedPassword');
|
|
200
200
|
if (signUpDto.roles && signUpDto.roles.length > 0) {
|
|
201
201
|
for (let i = 0; i < signUpDto.roles.length; i++) {
|
|
202
202
|
const roleName = signUpDto.roles[i];
|
|
@@ -217,7 +217,7 @@ export class AuthenticationService {
|
|
|
217
217
|
if (signUpDto.password) {
|
|
218
218
|
pwd = await this.hashingService.hash(signUpDto.password);
|
|
219
219
|
}
|
|
220
|
-
|
|
220
|
+
if(autoGeneratedPwdPermission?.toString().toLowerCase() === 'true'){
|
|
221
221
|
// TODO: If password is not specified then auto-generate a random password, trigger this password over an email to the user.
|
|
222
222
|
// TODO: Also track if the user has to force reset / change their password, and then activate the user.
|
|
223
223
|
autoGeneratedPwd = this.generatePassword();
|
|
@@ -764,13 +764,13 @@ export class AuthenticationService {
|
|
|
764
764
|
isValidUser = false
|
|
765
765
|
// throw new NotFoundException(ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
766
766
|
}
|
|
767
|
-
if (!user
|
|
767
|
+
if (isValidUser && !user?.active) {
|
|
768
768
|
isValidUser = false
|
|
769
769
|
// throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
770
770
|
}
|
|
771
771
|
|
|
772
772
|
// 2. Validate if user has used a provider which is "local", only then it makes sense for us to initiate the forgot password routine.
|
|
773
|
-
if (user
|
|
773
|
+
if (isValidUser && user?.lastLoginProvider !== 'local') {
|
|
774
774
|
isValidUser = false
|
|
775
775
|
// throw new BadRequestException(ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
776
776
|
}
|
|
@@ -792,8 +792,8 @@ export class AuthenticationService {
|
|
|
792
792
|
error: '',
|
|
793
793
|
errorCode: '',
|
|
794
794
|
data: {
|
|
795
|
-
user:
|
|
796
|
-
email: user
|
|
795
|
+
user: {
|
|
796
|
+
email: user?.email,
|
|
797
797
|
// mobile: user.mobile,
|
|
798
798
|
// username: user.username,
|
|
799
799
|
},
|