aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/GestureOverlay.tsx2
-rw-r--r--src/client/views/PropertiesView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx1
-rw-r--r--src/client/views/nodes/ImageBox.tsx1
-rw-r--r--src/client/views/smartdraw/SmartDrawHandler.tsx2
-rw-r--r--src/server/ApiManagers/AssistantManager.ts4
-rw-r--r--src/server/ApiManagers/AzureManager.ts43
-rw-r--r--src/server/ApiManagers/UserManager.ts29
-rw-r--r--src/server/RouteManager.ts46
-rw-r--r--src/server/authentication/AuthenticationManager.ts44
-rw-r--r--src/server/authentication/DashUserModel.ts87
-rw-r--r--src/server/authentication/Passport.ts13
12 files changed, 139 insertions, 134 deletions
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 8488c5293..113250a99 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -50,9 +50,7 @@ interface GestureOverlayProps {
* drew or perform the gesture's action
*/
export class GestureOverlay extends ObservableReactComponent<React.PropsWithChildren<GestureOverlayProps>> {
- // eslint-disable-next-line no-use-before-define
static Instance: GestureOverlay;
- // eslint-disable-next-line no-use-before-define
static Instances: GestureOverlay[] = [];
@observable public SavedColor?: string = undefined;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 5211272b0..f7c4b464c 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -58,7 +58,6 @@ interface PropertiesViewProps {
export class PropertiesView extends ObservableReactComponent<PropertiesViewProps> {
private _widthUndo?: UndoManager.Batch;
- // eslint-disable-next-line no-use-before-define
public static Instance: PropertiesView;
constructor(props: PropertiesViewProps) {
super(props);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 49c684ab1..73856f47b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -105,7 +105,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
/**
* The Freeformview below the cursor at the start of a gesture (that receives the pointerDown event). Used by GestureOverlay to determine the doc a gesture should apply to.
*/
- // eslint-disable-next-line no-use-before-define
public static DownFfview: CollectionFreeFormView | undefined; // the first DocView that receives a pointerdown event. used by GestureOverlay to determine the doc a gesture should apply to.
private _clusters = new CollectionFreeFormClusters(this);
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 4886f0e96..617a09ed5 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -49,7 +49,6 @@ import { gptImageLabel } from '../../apis/gpt/GPT';
const DefaultPath = '/assets/unknown-file-icon-hi.png';
export class ImageEditorData {
- // eslint-disable-next-line no-use-before-define
private static _instance: ImageEditorData;
private static get imageData() { return (ImageEditorData._instance ?? new ImageEditorData()).imageData; } // prettier-ignore
@observable imageData: { rootDoc: Doc | undefined; open: boolean; source: string; addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean> } = observable({ rootDoc: undefined, open: false, source: '', addDoc: undefined });
diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx
index b7ff5fff7..a017dd7eb 100644
--- a/src/client/views/smartdraw/SmartDrawHandler.tsx
+++ b/src/client/views/smartdraw/SmartDrawHandler.tsx
@@ -450,7 +450,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
},
}}
checked={this._generateDrawing}
- onChange={() => this._canInteract && (this._generateDrawing = !this._generateDrawing)}
+ onChange={action(() => this._canInteract && (this._generateDrawing = !this._generateDrawing))}
/>
</div>
<div className="image-checkbox">
diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts
index af25722a4..20ec0dfe6 100644
--- a/src/server/ApiManagers/AssistantManager.ts
+++ b/src/server/ApiManagers/AssistantManager.ts
@@ -439,9 +439,9 @@ export default class AssistantManager extends ApiManager {
try {
const image = await openai.images.generate({ model: 'dall-e-3', prompt: image_prompt, response_format: 'url' });
console.log(image);
- const result = await DashUploadUtils.UploadImage(image.data[0].url!);
+ const url = image.data?.[0].url;
- const url = image.data[0].url;
+ const result = url ? await DashUploadUtils.UploadImage(url) : { error: 'Image generation failed' };
res.send({ result, url });
} catch (error) {
diff --git a/src/server/ApiManagers/AzureManager.ts b/src/server/ApiManagers/AzureManager.ts
index 2d0ab3aa6..d54b15810 100644
--- a/src/server/ApiManagers/AzureManager.ts
+++ b/src/server/ApiManagers/AzureManager.ts
@@ -1,37 +1,38 @@
-import { ContainerClient, BlobServiceClient } from "@azure/storage-blob";
-import * as fs from "fs";
-import { Readable, Stream } from "stream";
-import * as path from "path";
+import { ContainerClient, BlobServiceClient } from '@azure/storage-blob';
+import * as fs from 'fs';
+import { Readable } from 'stream';
+import * as path from 'path';
const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING;
const extToType: { [suffix: string]: string } = {
- ".jpeg" : "image/jpeg",
- ".jpg" : "image/jpeg",
- ".png" : "image/png",
- ".svg" : "image/svg+xml",
- ".webp" : "image/webp",
- ".gif" : "image/gif"
-}
+ '.jpeg': 'image/jpeg',
+ '.jpg': 'image/jpeg',
+ '.png': 'image/png',
+ '.svg': 'image/svg+xml',
+ '.webp': 'image/webp',
+ '.gif': 'image/gif',
+};
export class AzureManager {
private _containerClient: ContainerClient;
private _blobServiceClient: BlobServiceClient;
private static _instance: AzureManager | undefined;
- public static CONTAINER_NAME = "dashmedia";
- public static STORAGE_ACCOUNT_NAME = "dashblobstore";
+ public static CONTAINER_NAME = 'dashmedia';
+ public static STORAGE_ACCOUNT_NAME = 'dashblobstore';
public static BASE_STRING = `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}`;
constructor() {
if (!AZURE_STORAGE_CONNECTION_STRING) {
- throw new Error("Azure Storage Connection String Not Found");
+ throw new Error('Azure Storage Connection String Not Found');
}
this._blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
this._containerClient = this.BlobServiceClient.getContainerClient(AzureManager.CONTAINER_NAME);
}
public static get Instance() {
- return this._instance = this._instance ?? new AzureManager();
+ this._instance = this._instance ?? new AzureManager();
+ return this._instance;
}
public get BlobServiceClient() {
@@ -44,14 +45,14 @@ export class AzureManager {
public static UploadBlob(filename: string, filepath: string, filetype: string) {
const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
- const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }};
+ const blobOptions = { blobHTTPHeaders: { blobContentType: filetype } };
const stream = fs.createReadStream(filepath);
return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions);
}
public static UploadBase64ImageBlob(filename: string, data: string, filetype?: string) {
const confirmedFiletype = filetype ? filetype : extToType[path.extname(filename)];
- const buffer = Buffer.from(data, "base64");
+ const buffer = Buffer.from(data, 'base64');
const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
const blobOptions = { blobHTTPHeaders: { blobContentType: confirmedFiletype } };
return blockBlobClient.upload(buffer, buffer.length, blobOptions);
@@ -59,7 +60,7 @@ export class AzureManager {
public static UploadBlobStream(stream: Readable, filename: string, filetype: string) {
const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
- const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }};
+ const blobOptions = { blobHTTPHeaders: { blobContentType: filetype } };
return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions);
}
@@ -74,9 +75,9 @@ export class AzureManager {
console.log(`${blob.name}`);
const blobItem = {
- url : `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}/${blob.name}`,
- name : blob.name
- }
+ url: `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}/${blob.name}`,
+ name: blob.name,
+ };
foundBlobs.push(blobItem);
}
diff --git a/src/server/ApiManagers/UserManager.ts b/src/server/ApiManagers/UserManager.ts
index b587340e2..b42c974ac 100644
--- a/src/server/ApiManagers/UserManager.ts
+++ b/src/server/ApiManagers/UserManager.ts
@@ -22,6 +22,7 @@ export default class UserManager extends ApiManager {
secureHandler: async ({ res }) => {
const cursor = await Database.Instance.query({}, { email: 1, linkDatabaseId: 1, sharingDocumentId: 1 }, 'users');
const results = await cursor.toArray();
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
res.send(results.map((user: any) => ({ email: user.email, linkDatabaseId: user.linkDatabaseId, sharingDocumentId: user.sharingDocumentId })));
},
});
@@ -31,9 +32,10 @@ export default class UserManager extends ApiManager {
subscription: '/setCacheDocumentIds',
secureHandler: async ({ user, req, res }) => {
const userModel = user;
- const result: any = {};
+ const result: { error?: unknown } = {};
userModel.cacheDocumentIds = req.body.cacheDocumentIds;
- userModel.save().then(undefined, (err: any) => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ userModel.save?.().then(undefined, (err: any) => {
if (err) {
result.error = [{ msg: 'Error while caching documents' }];
}
@@ -90,20 +92,19 @@ export default class UserManager extends ApiManager {
subscription: '/internalResetPassword',
secureHandler: async ({ user, req, res }) => {
const userModel = user;
- const result: any = {};
- // eslint-disable-next-line camelcase
+ const result: { error?: unknown } = {};
const { curr_pass, new_pass } = req.body;
// perhaps should assert whether curr password is entered correctly
const validated = await new Promise<Opt<boolean>>(resolve => {
- bcrypt.compare(curr_pass, userModel.password, (err, passwordsMatch) => {
- if (err || !passwordsMatch) {
- result.error = [{ msg: 'Incorrect current password' }];
- res.send(result);
- resolve(undefined);
- } else {
- resolve(passwordsMatch);
- }
- });
+ userModel.password &&
+ bcrypt.compare(curr_pass, userModel.password, (err, passwordsMatch) => {
+ if (err || !passwordsMatch) {
+ res.send({ error: [{ msg: 'Incorrect current password' }] });
+ resolve(undefined);
+ } else {
+ resolve(passwordsMatch);
+ }
+ });
});
if (validated === undefined) {
@@ -133,7 +134,7 @@ export default class UserManager extends ApiManager {
userModel.passwordResetExpires = undefined;
}
- userModel.save().then(undefined, err => {
+ userModel.save?.().then(undefined, err => {
if (err) {
result.error = [{ msg: 'Error while saving new password' }];
}
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index c5d70da3d..ed51aea40 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -18,10 +18,11 @@ export interface CoreArguments {
isRelease: boolean;
}
-export type AuthorizedCore = CoreArguments & { user: DashUserModel };
-export type SecureHandler = (core: AuthorizedCore) => any | Promise<any>;
-export type PublicHandler = (core: CoreArguments) => any | Promise<any>;
-export type ErrorHandler = (core: CoreArguments & { error: any }) => any | Promise<any>;
+export type AuthorizedCore = CoreArguments & { user: Partial<DashUserModel> };
+export type SecureHandler = (core: AuthorizedCore) => unknown | Promise<unknown>;
+export type PublicHandler = (core: CoreArguments) => unknown | Promise<unknown>;
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export type ErrorHandler = (core: CoreArguments & { error: any }) => unknown | Promise<unknown>;
export const STATUS = {
OK: 200,
@@ -30,13 +31,14 @@ export const STATUS = {
PERMISSION_DENIED: 403,
};
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function _error(res: Response, message: string, error?: any) {
console.error(message, error);
res.statusMessage = message;
res.status(STATUS.EXECUTION_ERROR).send(error);
}
-export function _success(res: Response, body: any) {
+export function _success(res: Response, body: unknown) {
res.status(STATUS.OK).send(body);
}
@@ -135,18 +137,6 @@ export default class RouteManager {
user = { id: 'guest', email: 'guest', userDocumentId: Utils.GuestID() };
}
const core = { req, res, isRelease };
- const tryExecute = async (toExecute: (args: any) => any | Promise<any>, args: any) => {
- try {
- await toExecute(args);
- } catch (e) {
- console.log(red(target), user && 'email' in user ? '<user logged out>' : undefined);
- if (errorHandler) {
- errorHandler({ ...core, error: e });
- } else {
- _error(res, `The server encountered an internal error when serving ${target}.`, e);
- }
- }
- };
if (user) {
if (requireAdmin && isRelease && process.env.PASSWORD) {
if (AdminPrivileges.get(user.id)) {
@@ -156,11 +146,29 @@ export default class RouteManager {
return;
}
}
- await tryExecute(secureHandler, { ...core, user });
+ try {
+ await secureHandler({ ...core, user });
+ } catch (e) {
+ console.log(red(target), user && 'email' in user ? '<user logged out>' : undefined);
+ if (errorHandler) {
+ errorHandler({ ...core, error: e });
+ } else {
+ _error(res, `The server encountered an internal error when serving ${target}.`, e);
+ }
+ }
}
// req.session!.target = target;
else if (publicHandler) {
- await tryExecute(publicHandler, core);
+ try {
+ await publicHandler(core);
+ } catch (e) {
+ console.log(red(target), user && 'email' in user ? '<user logged out>' : undefined);
+ if (errorHandler) {
+ errorHandler({ ...core, error: e });
+ } else {
+ _error(res, `The server encountered an internal error when serving ${target}.`, e);
+ }
+ }
if (!res.headersSent) {
// res.redirect("/login");
}
diff --git a/src/server/authentication/AuthenticationManager.ts b/src/server/authentication/AuthenticationManager.ts
index 0cc1553c0..3c7858a72 100644
--- a/src/server/authentication/AuthenticationManager.ts
+++ b/src/server/authentication/AuthenticationManager.ts
@@ -26,21 +26,12 @@ export const getSignup = (req: Request, res: Response) => {
return undefined;
};
-const tryRedirectToTarget = (req: Request, res: Response) => {
- const target = (req.session as any)?.target;
- if (req.session && target) {
- res.redirect(target);
- } else {
- res.redirect('/home');
- }
-};
-
/**
* POST /signup
* Create a new local account.
*/
export const postSignup = (req: Request, res: Response, next: NextFunction) => {
- const email = req.body.email as String;
+ const email = req.body.email as string;
check('email', 'Email is not valid').isEmail().run(req);
check('password', 'Password must be at least 4 characters long').isLength({ min: 4 }).run(req);
check('confirmPassword', 'Passwords do not match').equals(req.body.password).run(req);
@@ -66,7 +57,7 @@ export const postSignup = (req: Request, res: Response, next: NextFunction) => {
const user = new User(model);
User.findOne({ email })
- .then((existingUser: any) => {
+ .then((existingUser: DashUserModel | null) => {
if (existingUser) {
return res.redirect('/login');
}
@@ -74,13 +65,15 @@ export const postSignup = (req: Request, res: Response, next: NextFunction) => {
.then(() => {
req.logIn(user, err => {
if (err) return next(err);
- tryRedirectToTarget(req, res);
+ res.redirect('/home');
return undefined;
});
})
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
.catch((err: any) => next(err));
return undefined;
})
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
.catch((err: any) => next(err));
return undefined;
};
@@ -108,7 +101,8 @@ export const getLogin = (req: Request, res: Response) => {
export const postLogin = (req: Request, res: Response, next: NextFunction) => {
if (req.body.email === '') {
User.findOne({ email: 'guest' })
- .then((user: any) => !user && initializeGuest())
+ .then((user: DashUserModel | null) => !user && initializeGuest())
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
.catch((err: any) => err);
req.body.email = 'guest';
req.body.password = 'guest';
@@ -132,7 +126,7 @@ export const postLogin = (req: Request, res: Response, next: NextFunction) => {
req.logIn(user, loginErr => {
if (loginErr) {
next(loginErr);
- } else tryRedirectToTarget(req, res);
+ } else res.redirect('/home');
});
return undefined;
};
@@ -163,15 +157,15 @@ export const postForgot = function (req: Request, res: Response, next: NextFunct
const { email } = req.body;
async.waterfall(
[
- function (done: any) {
- c.randomBytes(20, (err: any, buffer: Buffer) => {
+ function (done: (arg: null, token?: string) => void) {
+ c.randomBytes(20, (err: Error | null, buffer: Buffer) => {
if (err) {
done(null);
} else done(null, buffer.toString('hex'));
});
},
- function (token: string, done: any) {
- User.findOne({ email }).then((user: any) => {
+ function (token: string, done: (arg: null, token: string, user: DashUserModel) => void) {
+ User.findOne({ email }).then((user: DashUserModel | null) => {
if (!user) {
// NO ACCOUNT WITH SUBMITTED EMAIL
res.redirect('/forgotPassword');
@@ -182,7 +176,7 @@ export const postForgot = function (req: Request, res: Response, next: NextFunct
user.save().then(() => done(null, token, user));
});
},
- function (token: Uint16Array, user: DashUserModel, done: any) {
+ function (token: Uint16Array, user: DashUserModel, done: (arg: null, token: Error | null, data: string) => void) {
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
@@ -220,7 +214,7 @@ export const postForgot = function (req: Request, res: Response, next: NextFunct
export const getReset = function (req: Request, res: Response) {
User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } })
- .then((user: any) => {
+ .then((user: DashUserModel | null) => {
if (!user) return res.redirect('/forgotPassword');
res.render('reset.pug', {
title: 'Reset Password',
@@ -234,9 +228,9 @@ export const getReset = function (req: Request, res: Response) {
export const postReset = function (req: Request, res: Response) {
async.waterfall(
[
- function (done: any) {
+ function (done: (args: null, user: DashUserModel) => void) {
User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } })
- .then((user: any) => {
+ .then((user: DashUserModel | null) => {
if (!user) return res.redirect('back');
check('password', 'Password must be at least 4 characters long').isLength({ min: 4 }).run(req);
@@ -250,8 +244,8 @@ export const postReset = function (req: Request, res: Response) {
user.save()
.then(
- () => (req as any).logIn(user),
- (err: any) => err
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ () => req.logIn(user, (err: any) => err)
)
.catch(() => res.redirect('/login'));
done(null, user);
@@ -259,7 +253,7 @@ export const postReset = function (req: Request, res: Response) {
})
.catch(() => res.redirect('back'));
},
- function (user: DashUserModel, done: any) {
+ function (user: DashUserModel, done: (args: null, error: Error | null) => void) {
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
diff --git a/src/server/authentication/DashUserModel.ts b/src/server/authentication/DashUserModel.ts
index 6fd8dd593..7aa7f2598 100644
--- a/src/server/authentication/DashUserModel.ts
+++ b/src/server/authentication/DashUserModel.ts
@@ -3,30 +3,31 @@ import * as mongoose from 'mongoose';
import { Utils } from '../../Utils';
type comparePasswordFunction = (candidatePassword: string, cb: (err: Error, isMatch: boolean) => void) => void;
-type mongooseDocument = { id: string }; // & mongoose.Document;
-export type DashUserModel = mongooseDocument & {
- email: string;
- password: string;
- passwordResetToken?: string;
- passwordResetExpires?: Date;
+export type DashUserModel = mongoose.Document & {
+ email?: string | null | undefined;
+ password?: string | null | undefined;
+ passwordResetToken?: string | null | undefined;
+ passwordResetExpires?: Date | null | undefined;
- dropboxRefresh?: string;
- dropboxToken?: string;
+ dropboxRefresh?: string | null | undefined;
+ dropboxToken?: string | null | undefined;
- userDocumentId: string;
- sharingDocumentId: string;
- linkDatabaseId: string;
- cacheDocumentIds: string;
+ userDocumentId?: string | null | undefined;
+ sharingDocumentId?: string | null | undefined;
+ linkDatabaseId?: string | null | undefined;
+ cacheDocumentIds?: string | null | undefined;
+ profile?:
+ | {
+ name?: string | null | undefined;
+ gender?: string | null | undefined;
+ location?: string | null | undefined;
+ website?: string | null | undefined;
+ picture?: string | null | undefined;
+ }
+ | null
+ | undefined;
- profile: {
- name: string;
- gender: string;
- location: string;
- website: string;
- picture: string;
- };
-
- comparePassword: comparePasswordFunction;
+ comparePassword?: comparePasswordFunction | null | undefined;
};
export type AuthToken = {
@@ -68,36 +69,38 @@ const userSchema = new mongoose.Schema(
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
userSchema.pre('save', function save(next: any) {
- const user = this;
- if (!user.isModified('password')) {
+ if (!this.isModified('password')) {
return next();
}
- bcrypt.genSalt(10, (err: Error, salt: string) => {
- if (err) {
- return next(err);
- }
- bcrypt.hash(
- user.password ?? '',
- salt,
- () => {},
- (cryptErr: mongoose.Error, hash: string) => {
- if (cryptErr) {
- return next(cryptErr);
- }
- user.password = hash;
- next();
- return undefined;
+ bcrypt.genSalt(
+ 10,
+ ((err: Error, salt: string) => {
+ if (err) {
+ return next(err);
}
- );
- return undefined;
- });
+ bcrypt.hash(
+ this.password ?? '',
+ salt,
+ () => {},
+ (cryptErr: mongoose.Error, hash: string) => {
+ if (cryptErr) {
+ return next(cryptErr);
+ }
+ this.password = hash;
+ next();
+ return undefined;
+ }
+ );
+ return undefined;
+ }).bind(this)
+ );
return undefined;
});
const comparePassword: comparePasswordFunction = function (this: DashUserModel, candidatePassword, cb) {
// Choose one of the following bodies for authentication logic.
// secure (expected, default)
- bcrypt.compare(candidatePassword, this.password, cb);
+ this.password && bcrypt.compare(candidatePassword, this.password, cb);
// bypass password (debugging)
// cb(undefined, true);
};
diff --git a/src/server/authentication/Passport.ts b/src/server/authentication/Passport.ts
index a62d38e3e..38a99bd45 100644
--- a/src/server/authentication/Passport.ts
+++ b/src/server/authentication/Passport.ts
@@ -1,25 +1,28 @@
import * as passport from 'passport';
import * as passportLocal from 'passport-local';
import User, { DashUserModel } from './DashUserModel';
+import { IncomingMessage } from 'webpack-dev-middleware';
const LocalStrategy = passportLocal.Strategy;
-passport.serializeUser<any, any>((req, user, done) => {
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+passport.serializeUser<any, IncomingMessage & DashUserModel>((req, user, done) => {
done(undefined, (user as DashUserModel)?.id);
});
-passport.deserializeUser<any, any>((id, done) => {
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+passport.deserializeUser<any, IncomingMessage & DashUserModel>((id, done) => {
User.findById(id)
.exec()
- .then((user: DashUserModel) => done(undefined, user));
+ .then((user: DashUserModel | null) => user && done(undefined, user));
});
// AUTHENTICATE JUST WITH EMAIL AND PASSWORD
passport.use(
new LocalStrategy({ usernameField: 'email', passReqToCallback: true }, (req, email, password, done) => {
User.findOne({ email: email.toLowerCase() })
- .then((user: DashUserModel) => {
- if (!user) {
+ .then((user: DashUserModel | null) => {
+ if (!user?.comparePassword) {
done(undefined, false, { message: 'Invalid email or password' }); // invalid email
} else {
user.comparePassword(password, (error: Error, isMatch: boolean) => {