diff --git a/src/client.ts b/src/client.ts index e80b148..f6915b3 100644 --- a/src/client.ts +++ b/src/client.ts @@ -33,7 +33,7 @@ function makeClient (app: Application, _options?: Partial): Authe const authManagement = app.service(path); const client: AuthenticationManagementClient = { - checkUnique: async (identifyUser: IdentifyUser, ownId: NullableId, ifErrMsg?: boolean) => { + checkUnique: async (identifyUser: IdentifyUser, ownId?: NullableId, ifErrMsg?: boolean) => { await authManagement.create({ action: 'checkUnique', value: identifyUser, @@ -129,7 +129,7 @@ function makeClient (app: Application, _options?: Partial): Authe try { if (!user || !user.isVerified) { await app.logout(); - return cb(new Error(user ? 'User\'s email is not verified.' : 'No user returned.')); + return cb && cb(new Error(user ? 'User\'s email is not verified.' : 'No user returned.')); } if (cb) { @@ -140,7 +140,7 @@ function makeClient (app: Application, _options?: Partial): Authe return user; } catch (err) { if (!cbCalled && cb) { - cb(err); + cb(err as Error); } } } diff --git a/src/helpers/hash-password.ts b/src/helpers/hash-password.ts index 4cd121f..a4501cc 100644 --- a/src/helpers/hash-password.ts +++ b/src/helpers/hash-password.ts @@ -7,7 +7,7 @@ export async function hashPassword ( field: string ): Promise { if (!field) throw new Error('Field is missing'); - const context = { + const context: Partial = { type: 'before', data: { [field]: password }, params: { provider: null }, diff --git a/src/helpers/sanitize-user-for-client.ts b/src/helpers/sanitize-user-for-client.ts index 1fde79b..3e56fd6 100644 --- a/src/helpers/sanitize-user-for-client.ts +++ b/src/helpers/sanitize-user-for-client.ts @@ -2,7 +2,7 @@ import { cloneObject } from './clone-object'; import type { User } from '../types'; export function sanitizeUserForClient ( - _user: User + _user: Partial ): Record { const user = cloneObject(_user); diff --git a/src/helpers/sanitize-user-for-notifier.ts b/src/helpers/sanitize-user-for-notifier.ts index f0ef31c..e89f0c5 100644 --- a/src/helpers/sanitize-user-for-notifier.ts +++ b/src/helpers/sanitize-user-for-notifier.ts @@ -1,7 +1,7 @@ import { cloneObject } from './clone-object'; import type { User } from '../types'; -export function sanitizeUserForNotifier (_user: User): Record { +export function sanitizeUserForNotifier (_user: Partial): Record { const user = cloneObject(_user); delete user.password; return user; diff --git a/src/helpers/typescript.ts b/src/helpers/typescript.ts new file mode 100644 index 0000000..83d0916 --- /dev/null +++ b/src/helpers/typescript.ts @@ -0,0 +1,3 @@ +export function typedObjectKeys(o: T): Array { + return Object.keys(o) as Array; +} diff --git a/src/hooks/add-verification.ts b/src/hooks/add-verification.ts index e2b3abe..7ab4892 100644 --- a/src/hooks/add-verification.ts +++ b/src/hooks/add-verification.ts @@ -55,8 +55,9 @@ export function addVerification ( ); return context; - } catch (err) { - throw new GeneralError(err); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (err: any) { + throw new GeneralError(err?.message); } }; } diff --git a/src/hooks/remove-verification.ts b/src/hooks/remove-verification.ts index 2e9555e..584e01f 100644 --- a/src/hooks/remove-verification.ts +++ b/src/hooks/remove-verification.ts @@ -12,8 +12,8 @@ export function removeVerification ( return (context: H): H => { checkContext(context, 'after'); // Retrieve the items from the hook - const items: User | User[] = getItems(context); - if (!items) return; + const items: Partial | Partial[] = getItems(context); + if (!items) return context; const isArray = Array.isArray(items); const users = (isArray ? items : [items]); diff --git a/src/methods/check-unique.ts b/src/methods/check-unique.ts index a239dc6..6366703 100644 --- a/src/methods/check-unique.ts +++ b/src/methods/check-unique.ts @@ -1,6 +1,7 @@ import { BadRequest } from '@feathersjs/errors'; import makeDebug from 'debug'; +import { typedObjectKeys } from '../helpers/typescript'; import type { NullableId, Params } from '@feathersjs/feathers'; import type { CheckUniqueOptions, @@ -33,10 +34,10 @@ export default async function checkUnique ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; const errProps = []; - const keys = Object.keys(identifyUser).filter( + const keys = typedObjectKeys(identifyUser).filter( key => identifyUser[key] != null ); @@ -59,16 +60,17 @@ export default async function checkUnique ( errProps.push(prop); } } - } catch (err) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (err: any) { throw new BadRequest( meta?.noErrMsg ? null : 'checkUnique unexpected error.', - { errors: { msg: err.message, $className: 'unexpected' } } + { errors: { msg: err?.message, $className: 'unexpected' } } ); } if (errProps.length) { - const errs = {}; - errProps.forEach(prop => { errs[prop] = 'Already taken.'; }); + const errs: Record = {}; + errProps.forEach((prop ) => { errs[prop] = 'Already taken.'; }); throw new BadRequest( meta?.noErrMsg ? null : 'Values already taken.', diff --git a/src/methods/identity-change.ts b/src/methods/identity-change.ts index 1f2d632..2f2e746 100644 --- a/src/methods/identity-change.ts +++ b/src/methods/identity-change.ts @@ -31,7 +31,7 @@ export default async function identityChange ( } const usersService = options.app.service(options.service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; const { delay, identifyUserProps, diff --git a/src/methods/password-change.ts b/src/methods/password-change.ts index cd76e94..14acea0 100644 --- a/src/methods/password-change.ts +++ b/src/methods/password-change.ts @@ -46,7 +46,7 @@ export default async function passwordChange ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; ensureValuesAreStrings(oldPassword, password); ensureObjPropsValid(identifyUser, identifyUserProps); diff --git a/src/methods/resend-verify-signup.ts b/src/methods/resend-verify-signup.ts index fa3e9ca..6dde4d9 100644 --- a/src/methods/resend-verify-signup.ts +++ b/src/methods/resend-verify-signup.ts @@ -23,7 +23,7 @@ const debug = makeDebug('authLocalMgnt:resendVerifySignup'); export default async function resendVerifySignup ( options: ResendVerifySignupOptions, identifyUser: IdentifyUser, - notifierOptions: NotifierOptions, + notifierOptions?: NotifierOptions, params?: Params ): Promise { debug('identifyUser=', identifyUser); @@ -46,7 +46,7 @@ export default async function resendVerifySignup ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; ensureObjPropsValid(identifyUser, identifyUserProps.concat('verifyToken', 'verifyShortToken') diff --git a/src/methods/reset-password.ts b/src/methods/reset-password.ts index 2cc3cf3..06cfe8e 100644 --- a/src/methods/reset-password.ts +++ b/src/methods/reset-password.ts @@ -9,6 +9,7 @@ import { hashPassword, notify } from '../helpers'; +import { typedObjectKeys } from '../helpers/typescript'; import type { Id, Params } from '@feathersjs/feathers'; import type { @@ -90,7 +91,7 @@ async function resetPassword ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; let users; if (tokens.resetToken) { @@ -114,7 +115,7 @@ async function resetPassword ( const user = getUserData(users, checkProps); // compare all tokens (hashed) - const tokenChecks = Object.keys(tokens).map(async key => { + const tokenChecks = typedObjectKeys(tokens).map(async key => { if (reuseResetToken) { // Comparing token directly as reused resetToken is not hashed if (tokens[key] !== user[key]) { @@ -124,7 +125,7 @@ async function resetPassword ( } } else { return await comparePasswords( - tokens[key], + tokens[key]!, user[key] as string, () => new BadRequest( diff --git a/src/methods/send-reset-pwd.ts b/src/methods/send-reset-pwd.ts index fca976b..fd0b5e4 100644 --- a/src/methods/send-reset-pwd.ts +++ b/src/methods/send-reset-pwd.ts @@ -51,7 +51,7 @@ export default async function sendResetPwd ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; ensureObjPropsValid(identifyUser, identifyUserProps); diff --git a/src/methods/verify-signup-set-password.ts b/src/methods/verify-signup-set-password.ts index 4fe8032..afbecea 100644 --- a/src/methods/verify-signup-set-password.ts +++ b/src/methods/verify-signup-set-password.ts @@ -8,6 +8,7 @@ import { isDateAfterNow, notify } from '../helpers'; +import { typedObjectKeys } from '../helpers/typescript'; import type { Id, Params } from '@feathersjs/feathers'; import type { VerifyChanges } from '..'; @@ -91,7 +92,7 @@ async function verifySignupSetPassword ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; const users = await usersService.find({ ...params, @@ -103,7 +104,7 @@ async function verifySignupSetPassword ( 'verifyNotExpired' ]); - if (!Object.keys(tokens).every((key) => tokens[key] === user[key])) { + if (!typedObjectKeys(tokens).every((key) => tokens[key] === user[key])) { await eraseVerifyProps(user, user.isVerified, params); throw new BadRequest( diff --git a/src/methods/verify-signup.ts b/src/methods/verify-signup.ts index eec904d..ab4b74a 100644 --- a/src/methods/verify-signup.ts +++ b/src/methods/verify-signup.ts @@ -7,6 +7,7 @@ import { notify, isDateAfterNow } from '../helpers'; +import { typedObjectKeys } from '../helpers/typescript'; import type { Id, Params } from '@feathersjs/feathers'; import type { @@ -82,7 +83,7 @@ async function verifySignup ( } = options; const usersService = app.service(service); - const usersServiceId = usersService.id; + const usersServiceId = usersService.id!; const users = await usersService.find( { @@ -98,7 +99,7 @@ async function verifySignup ( let userErasedVerify: User; - if (!Object.keys(tokens).every(key => tokens[key] === user[key])) { + if (!typedObjectKeys(tokens).every((key) => tokens[key] === user[key])) { userErasedVerify = await eraseVerifyProps(user, user.isVerified); throw new BadRequest( diff --git a/src/options.ts b/src/options.ts index 0b1db37..334695d 100644 --- a/src/options.ts +++ b/src/options.ts @@ -14,7 +14,7 @@ export const defaultPath = 'authManagement'; export const optionsDefault: AuthenticationManagementServiceOptions = { service: '/users', // need exactly this for test suite // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function - notifier: async (type: NotificationType, user: User, notifierOptions) => {}, + notifier: async (type: NotificationType, user: Partial, notifierOptions) => {}, longTokenLen: 15, // token's length will be twice this shortTokenLen: 6, shortTokenDigits: true, diff --git a/src/services/AuthenticationManagementBase.ts b/src/services/AuthenticationManagementBase.ts index 09a9993..6be13c9 100644 --- a/src/services/AuthenticationManagementBase.ts +++ b/src/services/AuthenticationManagementBase.ts @@ -1,9 +1,12 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { MethodNotAllowed } from '@feathersjs/errors'; import type { Application, Params } from '@feathersjs/feathers'; export abstract class AuthenticationManagementBase { - publish: unknown; + publish: undefined | ((fn: ((...any: any[]) => unknown)) => void); app: Application; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore not defined in constructor but is used. options: O; abstract _create (data: T, params?: Params): Promise; @@ -31,7 +34,7 @@ export abstract class AuthenticationManagementBase { } async setup (): Promise { - if (typeof this.publish === 'function') { + if (typeof this.publish === 'function') { this.publish(() => null); } } diff --git a/src/types.ts b/src/types.ts index a77fecc..6981094 100644 --- a/src/types.ts +++ b/src/types.ts @@ -116,7 +116,7 @@ export interface AuthenticationManagementServiceOptions { * @default 'password' */ passwordField: string /** Pass params from f-a-m service to `/users` service */ - passParams: (params) => Params | Promise + passParams?: (params: any) => Params | Promise } export type AuthenticationManagementSetupOptions = AuthenticationManagementServiceOptions & { path: string }; diff --git a/tsconfig.json b/tsconfig.json index b0bc86a..d0f0fe3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "sourceMap": false, "declaration": true, "strictNullChecks": false, + "noImplicitAny": true, }, "include": [ "src/**/*"