Skip to content

User - Service

CrudUserService has prebuilt commands you can use to manage your users.

Some commands make use of the EmailService. The CLI's setup has a shell service that you can complete with your mailing provider api.

services/email/email.service.ts
export class EmailService extends CrudService<Email> implements EmailService {
    //...
    sendVerificationEmail(to: string, token: string, ctx: CrudContext): Promise<any> {
        console.log('Sending verification email to', to, 'with token', token);
        return Promise.resolve();
    }
    sendTwoFactorEmail(to: string, code: string, ctx: CrudContext): Promise<any> {
        console.log('Sending two factor email to', to, 'with code', code);
        return Promise.resolve();
    }
    sendPasswordResetEmail(to: string, token: string, ctx: CrudContext): Promise<any> {
        console.log('Sending password reset email to', to, 'with token', token);
        return Promise.resolve();
    }
}
Each command must be allowed in the security before usage.

Account creation

$create_account

create_account.security.ts
guest: {
    async defineCMDAbility(can, cannot, ctx) {
        can('create_account', 'user', { role: 'user' });
        // guest can create_account with role == 'user'
    }
}
import { ICreateAccountDto } from '@eicrud/shared/interfaces';

const dto: ICreateAccountDto = {
    email: 'new.user@mail.com',
    password: 'p4ssw0rd',
    role: 'user',
};
const { userId } = await userClient.cmdS('create_account', dto);

Authentication

$login

login.security.ts
guest: {
    async defineCMDAbility(can, cannot, ctx) {
        can('login', 'user');
        // guest can login
    }
}
import { ILoginDto } from '@eicrud/shared/interfaces';

const dto: ILoginDto = {
    email: 'new.user@mail.com',
    password: 'p4ssw0rd',
};

await userClient.login(dto);

$check_jwt

login.check_jwt.ts
guest: {
    async defineCMDAbility(can, cannot, ctx) {
        can('check_jwt', 'user');
        // guest can check_jwt
    }
}
const userId = await userClient.checkJwt();

if(userId){
    console.log(`${userId} is logged in`) 
}

Note

Authentication commands have their own methods in the client for ease of use. Check out the client page for more information.

Email management

$send_verification_email

send_verification_email.security.ts
user: {
    async defineCMDAbility(can, cannot, ctx) {
        can('send_verification_email', 'user');
        // user can send_verification_email
    }
}
import { ISendVerificationEmailDto } from '@eicrud/shared/interfaces';

// verify current email
await userClient.cmdS('send_verification_email', {});

// change email
const dto: ISendVerificationEmailDto = {
    newEmail: 'new-email@mail.com',
    password: 'p4ssw0rd',
};
await userClient.cmdS('send_verification_email', dto);

$verify_email

verify_email.security.ts
guest: {
    async defineCMDAbility(can, cannot, ctx) {
        can('verify_email', 'user');
        // guest can verify_email
    }
}
import { IVerifyTokenDto } from '@eicrud/shared/interfaces';

const dto: IVerifyTokenDto = {
    token_id: "k2Urz2b703aP6zQ_4d3ed089fb60ab534684b7ff"
    // email received token 
};
await userClient.cmdS('verify_email', dto);

Password management

$send_password_reset_email

send_password_reset_email.security.ts
guest: {
    async defineCMDAbility(can, cannot, ctx) {
        can('send_password_reset_email', 'user');
        // guest can send_password_reset_email
    }
}
import { ISendPasswordResetEmailDto } from '@eicrud/shared/interfaces';

const dto: ISendPasswordResetEmailDto = {
    email: "my-email@mail.com"
    // user email 
};
await userClient.cmdS('send_password_reset_email', dto);

$reset_password

reset_password.security.ts
guest: {
    async defineCMDAbility(can, cannot, ctx) {
        can('reset_password', 'user');
        // guest can reset_password
    }
}
import { IResetPasswordDto } from '@eicrud/shared/interfaces';

const dto: IResetPasswordDto = {
    token_id: "k2Urz2b703aP6zQ_4d3ed089fb60ab534684b7ff",
    // email received token 
    newPassword: "w0rdp4ss",
    logMeIn: true,
    expiresInSec: 60*30
    // log user for 30 min
};
const { accessToken } = await userClient.cmdS('reset_password', dto);

$change_password

change_password.security.ts
user: {
    async defineCMDAbility(can, cannot, ctx) {
        can('change_password', 'user');
        // user can change_password
    }
}
import { IChangePasswordDto } from '@eicrud/shared/interfaces';

const dto: IChangePasswordDto = {
    oldPassword: "p4ssw0rd",
    newPassword: "w0rdp4ss",
    logMeIn: true,
    expiresInSec: 60*30
    // log user for 30 min
};
const { accessToken } = await userClient.cmdS('change_password', dto);

Session kick

$logout_everywhere

logout_everywhere.security.ts
user: {
    async defineCMDAbility(can, cannot, ctx) {
        can('logout_everywhere', 'user', { userId: ctx.userId });
        // user can logout_everywhere for own userId
    }
}
import { IChangePasswordDto } from '@eicrud/shared/interfaces';

const dto: IUserIdDto = {
    userId
};
await userClient.cmdS('logout_everywhere', dto);

Note

Calling logout_everywhere will invalidate all issued tokens for a user. It is automatically called when updating fields included in AuthenticationOptions->fieldsThatResetRevokedCount.

Moderation

$timeout_user

timeout_user.security.ts
moderator: {
    async defineCMDAbility(can, cannot, ctx) {
          const dto: ITimeoutUserDto = ctx.data;
          const allowed = ['user', 'vip'];
          if (
            dto.allowedRoles?.length &&
            dto.allowedRoles.every((r) => allowed.includes(r))
          ) {
            can(baseCmds.timeoutUser.name, 'user');
          }
    }
}
import { ITimeoutUserDto } from '@eicrud/shared/interfaces';

const dto: ITimeoutUserDto = {
    userId: "507f191e810c19729de860ea",
    timeoutDurationMinutes: 10, // will ban user for 10 min
    allowedRoles: ['user'],
};

await userClient.cmdS('timeout_user', dto);

Comments