Skip to content

Commit 790ba5b

Browse files
committed
models/user: resolve types using definitions from attempt 1 PR with tests passing
1 parent 5f1efe8 commit 790ba5b

File tree

5 files changed

+36
-22
lines changed

5 files changed

+36
-22
lines changed

server/models/__test__/user.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe('User model', () => {
8686

8787
const found = await User.findByEmail('dave@example.com');
8888
expect(found).not.toBeNull();
89-
expect(found.username).toBe('dave');
89+
expect(found!.username).toBe('dave'); // found exists otherwise the previous expect would fail
9090
});
9191

9292
it('should find user by username (case insensitive)', async () => {
@@ -98,7 +98,7 @@ describe('User model', () => {
9898

9999
const found = await User.findByUsername('eve', { caseInsensitive: true });
100100
expect(found).not.toBeNull();
101-
expect(found.email).toBe('eve@example.com');
101+
expect(found!.email).toBe('eve@example.com'); // found exists otherwise the previous expect would fail
102102
});
103103

104104
it('should return null for wrong username/email', async () => {
@@ -115,7 +115,8 @@ describe('User model', () => {
115115
await user.save();
116116

117117
const savedUser = await User.findOne({ email: 'frank@example.com' });
118-
const keyObj = await savedUser.findMatchingKey('hashedApiKey');
118+
expect(savedUser).not.toBeNull();
119+
const keyObj = await savedUser!.findMatchingKey('hashedApiKey'); // savedUser exists otherwise the previous expect would fail
119120

120121
expect(keyObj.isMatch).toBe(true);
121122
expect(keyObj.keyDocument).not.toBeNull();

server/models/apiKey.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Schema } from 'mongoose';
2-
import { SanitisedApiKey, ApiKeyDocument, ApiKeyModel } from '../types/apiKey';
2+
import { SanitisedApiKey, ApiKeyDocument, ApiKeyModel } from '../types';
33

44
export const apiKeySchema = new Schema<ApiKeyDocument, ApiKeyModel>(
55
{

server/models/user.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
import mongoose from 'mongoose';
1+
import mongoose, { Schema } from 'mongoose';
22
import bcrypt from 'bcryptjs';
3+
import {
4+
UserDocument,
5+
UserModel,
6+
CookieConsentOptions,
7+
EmailConfirmationStates
8+
} from '../types';
39
import { apiKeySchema } from './apiKey';
410

5-
const EmailConfirmationStates = {
6-
Verified: 'verified',
7-
Sent: 'sent',
8-
Resent: 'resent'
9-
};
10-
11-
const { Schema } = mongoose;
11+
// const EmailConfirmationStates = {
12+
// Verified: 'verified',
13+
// Sent: 'sent',
14+
// Resent: 'resent'
15+
// };
1216

13-
const userSchema = new Schema(
17+
const userSchema = new Schema<UserDocument, UserModel>(
1418
{
1519
name: { type: String, default: '' },
1620
username: { type: String, required: true, unique: true },
@@ -44,13 +48,13 @@ const userSchema = new Schema(
4448
totalSize: { type: Number, default: 0 },
4549
cookieConsent: {
4650
type: String,
47-
enum: ['none', 'essential', 'all'],
48-
default: 'none'
51+
enum: Object.values(CookieConsentOptions),
52+
default: CookieConsentOptions.NONE
4953
},
5054
banned: { type: Boolean, default: false },
5155
lastLoginTimestamp: { type: Date }
5256
},
53-
{ timestamps: true, usePushEach: true }
57+
{ timestamps: true }
5458
);
5559

5660
/**
@@ -67,6 +71,10 @@ userSchema.pre('save', function checkPassword(next) {
6771
next(err);
6872
return;
6973
}
74+
if (!user.password) {
75+
next(new Error('Password is missing'));
76+
return;
77+
}
7078
bcrypt.hash(user.password, salt, (innerErr, hash) => {
7179
if (innerErr) {
7280
next(innerErr);
@@ -92,7 +100,7 @@ userSchema.pre('save', function checkApiKey(next) {
92100
let pendingTasks = 0;
93101
let nextCalled = false;
94102

95-
const done = (err) => {
103+
const done = (err?: mongoose.CallbackError) => {
96104
if (nextCalled) return;
97105
if (err) {
98106
nextCalled = true;
@@ -144,7 +152,7 @@ userSchema.set('toJSON', {
144152
* @return {Promise<boolean>}
145153
*/
146154
userSchema.methods.comparePassword = async function comparePassword(
147-
candidatePassword
155+
candidatePassword: string
148156
) {
149157
if (!this.password) {
150158
return false;
@@ -162,7 +170,7 @@ userSchema.methods.comparePassword = async function comparePassword(
162170
* Helper method for validating a user's api key
163171
*/
164172
userSchema.methods.findMatchingKey = async function findMatchingKey(
165-
candidateKey
173+
candidateKey: string
166174
) {
167175
let keyObj = { isMatch: false, keyDocument: null };
168176
/* eslint-disable no-restricted-syntax */
@@ -332,9 +340,11 @@ userSchema.statics.findByEmailAndUsername = async function findByEmailAndUsernam
332340
return foundUser;
333341
};
334342

335-
userSchema.statics.EmailConfirmation = EmailConfirmationStates;
343+
// userSchema.statics.EmailConfirmation = EmailConfirmationStates;
336344

337345
userSchema.index({ username: 1 }, { collation: { locale: 'en', strength: 2 } });
338346
userSchema.index({ email: 1 }, { collation: { locale: 'en', strength: 2 } });
339347

340-
export const User = mongoose.models.User || mongoose.model('User', userSchema);
348+
export const User =
349+
(mongoose.models.User as UserModel) ||
350+
mongoose.model<UserDocument, UserModel>('User', userSchema);

server/types/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
export * from './apiKey';
12
export * from './email';
3+
export * from './mongoose';
4+
export * from './user';
25
export * from './userPreferences';

server/types/user.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface IUser {
88
id: string;
99
name: string;
1010
username: string;
11-
password?: string;
11+
password: string;
1212
resetPasswordToken?: string;
1313
resetPasswordExpires?: number;
1414
verified?: string;

0 commit comments

Comments
 (0)