diff --git a/package-lock.json b/package-lock.json index 4634c90ef..7ff35276b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,8 @@ "@types/fs-extra": "^11.0.3", "@types/jest": "^29.5.7", "@types/node": "^18.18.8", - "@types/node-schedule": "^2.1.2", + "@types/node-schedule": "^2.1.3", + "@types/passport-jwt": "^3.0.13", "@types/semver": "^7.5.4", "@types/tail": "^2.2.2", "@types/tar": "^6.1.7", @@ -2422,6 +2423,25 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -2461,6 +2481,30 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/fs-extra": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.3.tgz", @@ -2480,25 +2524,31 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz", - "integrity": "sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz", - "integrity": "sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -2515,9 +2565,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/json5": { @@ -2527,9 +2577,9 @@ "dev": true }, "node_modules/@types/jsonfile": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.3.tgz", - "integrity": "sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -2543,6 +2593,12 @@ "@types/node": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz", + "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==", + "dev": true + }, "node_modules/@types/node": { "version": "18.18.8", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", @@ -2552,20 +2608,83 @@ } }, "node_modules/@types/node-schedule": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-2.1.2.tgz", - "integrity": "sha512-pNf6vCw14EYbqo0Y1eLGhkyv9RhgvphrxpPk4bd1CqwsWbHCrLSVYpO+9NmKOCUSYwxG6eRaWDR3Y6C+4gtzow==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-2.1.3.tgz", + "integrity": "sha512-sTWHBCD+17XjHRuxkLwoC0VdxAx/TVNny+1DUxv8RTPJNZGuokEKiSiGag+v9XdrnJ/c36ObWi4HA3JiokvOQw==", "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/passport": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.15.tgz", + "integrity": "sha512-oHOgzPBp5eLI1U/7421qYV/ZySQXMYCBSfRkDe1tQ0YrIbLY/M/76qIXE7Bs7lFyvw1x5QqiNQ9imvh0fQHe9Q==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/passport-jwt": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-3.0.13.tgz", + "integrity": "sha512-fjHaC6Bv8EpMMqzTnHP32SXlZGaNfBPC/Po5dmRGYi2Ky7ljXPbGnOy+SxZqa6iZvFgVhoJ1915Re3m93zmcfA==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/jsonwebtoken": "*", + "@types/passport-strategy": "*" + } + }, + "node_modules/@types/passport-strategy": { + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz", + "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.6.tgz", + "integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==", + "dev": true + }, "node_modules/@types/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.3.tgz", + "integrity": "sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.4.tgz", + "integrity": "sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.2.tgz", @@ -4839,9 +4958,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.576", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz", - "integrity": "sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==", + "version": "1.4.577", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.577.tgz", + "integrity": "sha512-/5xHPH6f00SxhHw6052r+5S1xO7gHNc89hV7tqlvnStvKbSrDqc/u6AlwPvVWWNj+s4/KL6T6y8ih+nOY0qYNA==", "dev": true }, "node_modules/emittery": { diff --git a/package.json b/package.json index 11d44ef72..013236a23 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,8 @@ "@types/fs-extra": "^11.0.3", "@types/jest": "^29.5.7", "@types/node": "^18.18.8", - "@types/node-schedule": "^2.1.2", + "@types/node-schedule": "^2.1.3", + "@types/passport-jwt": "^3.0.13", "@types/semver": "^7.5.4", "@types/tail": "^2.2.2", "@types/tar": "^6.1.7", diff --git a/src/core/auth/auth.service.ts b/src/core/auth/auth.service.ts index 24617feed..83d34de51 100644 --- a/src/core/auth/auth.service.ts +++ b/src/core/auth/auth.service.ts @@ -39,6 +39,7 @@ export class AuthService { * Authenticate a user with their credentials * @param username * @param password + * @param otp */ async authenticate(username: string, password: string, otp?: string): Promise { try { @@ -86,10 +87,11 @@ export class AuthService { * Authenticate and provide a JWT response * @param username * @param password + * @param otp */ async signIn(username: string, password: string, otp?: string): Promise { const user = await this.authenticate(username, password, otp); - const token = await this.jwtService.sign(user); + const token = this.jwtService.sign(user); return { access_token: token, @@ -128,7 +130,7 @@ export class AuthService { const user = users.find(x => x.admin === true); // generate a token - const token = await this.jwtService.sign({ + const token = this.jwtService.sign({ username: user.username, name: user.name, admin: user.admin, @@ -147,15 +149,15 @@ export class AuthService { * All information about the user we need is stored in the payload * @param payload the decoded, verified jwt payload */ - async validateUser(payload): Promise { + async validateUser(payload: any): Promise { return payload; } /** * Verify a token is signed correctly - * @param token + * @param client */ - async verifyWsConnection(client) { + async verifyWsConnection(client: any) { try { return jwt.verify(client.handshake.query.token, this.configService.secrets.secretKey); } catch (e) { @@ -191,7 +193,7 @@ export class AuthService { } /** - * Setup the first user + * Set up the first user */ async setupFirstUser(user: UserDto) { if (this.configService.setupWizardComplete) { @@ -224,7 +226,7 @@ export class AuthService { } // generate a token - const token = await this.jwtService.sign({ + const token = this.jwtService.sign({ username: 'setup-wizard', name: 'setup-wizard', admin: true, @@ -239,7 +241,7 @@ export class AuthService { } /** - * Executed on startup to see if the auth file is setup yet + * Executed on startup to see if the auth file is set up yet */ async checkAuthFile() { if (!await fs.pathExists(this.configService.authPath)) { @@ -285,23 +287,21 @@ export class AuthService { } /** - * Return a user by it's id + * Return a user by id * @param id */ async findById(id: number): Promise { const users = await this.getUsers(); - const user = users.find(x => x.id === id); - return user; + return users.find(x => x.id === id); } /** - * Return a user by it's username + * Return a user by username * @param username */ async findByUsername(username: string): Promise { const users = await this.getUsers(); - const user = users.find(x => x.username === username); - return user; + return users.find(x => x.username === username); } /** @@ -317,7 +317,7 @@ export class AuthService { * Add a new user * @param user */ - async addUser(user) { + async addUser(user: UserDto) { const authfile = await this.getUsers(); const salt = await this.genSalt(); @@ -373,7 +373,7 @@ export class AuthService { /** * Updates a user - * @param userId + * @param id * @param update */ async updateUser(id: number, update: UserDto) { @@ -404,7 +404,7 @@ export class AuthService { } // update the auth.json - this.saveUserFile(authfile); + await this.saveUserFile(authfile); this.logger.log(`Updated user: ${user.username}`); return this.desensitiseUserProfile(user); @@ -413,7 +413,7 @@ export class AuthService { /** * Change a users own password */ - async updateOwnPassword(username, currentPassword: string, newPassword: string) { + async updateOwnPassword(username: string, currentPassword: string, newPassword: string) { const authfile = await this.getUsers(); const user = authfile.find(x => x.username === username); @@ -424,7 +424,7 @@ export class AuthService { // this will throw an error of the password is wrong await this.checkPassword(user, currentPassword); - // generate a new salf + // generate a new salt const salt = await this.genSalt(); user.hashedPassword = await this.hashPassword(newPassword, salt); user.salt = salt; diff --git a/src/core/auth/jwt.strategy.ts b/src/core/auth/jwt.strategy.ts index 03af2488f..932f5835b 100644 --- a/src/core/auth/jwt.strategy.ts +++ b/src/core/auth/jwt.strategy.ts @@ -16,7 +16,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) { }); } - async validate(payload) { + async validate(payload: any) { const user = await this.authService.validateUser(payload); if (!user) { throw new UnauthorizedException();