Username/Password Authentication 
The module a-authsimple provides out-of-the-box username/password authentication
How to Use 
1. Register a New User 
typescript
const jwt = await this.bean.auth.authenticate('a-authsimple:simple', {
  clientOptions: {
    username: 'tom',
    password: '123456',
    email: 'xxx@xxx.com',
    avatar: ':emoji:flower',
    confirmed: true,
  },
  state: {
    intention: 'register',
  },
});confirmed: If true, it means the user has already confirmed and no further activation operation is needed
- Shorthand:
 
typescript
const jwt = await this.bean.authSimple.authenticate({
  username: 'tom',
  password: '123456',
  email: 'xxx@xxx.com',
  avatar: ':emoji:flower',
  confirmed: true,
}, 'register');2. Login 
typescript
const jwt = await this.bean.auth.authenticate('a-authsimple:simple', {
  clientOptions: {
    username: 'tom',
    password: '123456',
  },
  state: {
    intention: 'login',
  },
});- Shorthand:
 
typescript
const jwt = await this.bean.authSimple.authenticate({
  username: 'tom',
  password: '123456',
}, 'login');3. Logout 
typescript
await this.bean.passport.signout();4. Configuration 
The module a-authsimple uses password-hash-salt to hash the password
Configuration can be modified in App Config
src/backend/config/config/config.ts
typescript
// modules
config.modules = {
  'a-authsimple': {
    passwordHash: {
      saltlen: 64,
      iterations: 10000,
      keylen: 64,
      digest: 'sha1',
    },
  },
};Source Code Analysis 
This section analyzes the core source code of the module a-authsimple to explain how to develop a new Auth Provider
For example, create an Auth Provider in the module a-authsimple: simple
1. CLI Command 
bash
$ vona :create:bean authProvider simple --module=a-authsimple2. Menu Command 
TIP
Context Menu - [Module Path]: Vona Bean/Auth Provider
Auth Provider Definition 
diff
export interface IAuthProviderSimpleClientRecord extends IAuthProviderClientRecord {}
export interface IAuthProviderSimpleClientOptions extends IAuthProviderClientOptions {
  username?: string;
  password?: string;
  email?: string;
  avatar?: string;
  locale?: keyof ILocaleInfos;
}
export interface IAuthProviderOptionsSimple extends IDecoratorAuthProviderOptions<
  keyof IAuthProviderSimpleClientRecord,
  IAuthProviderSimpleClientOptions
> {}
@AuthProvider<IAuthProviderOptionsSimple>()
class AuthProviderSimple {
  async verify(
    _args,
    clientOptions,
    _options,
    state,
  ) {
    if (state?.intention === 'register') {
      if (!clientOptions.username || !clientOptions.password) return this.app.throw(403);
      // authSimple: create
      const authSimple = await this.scope.service.authSimple.create(clientOptions.password);
      // profile
      const profile: IAuthUserProfile = {
        id: authSimple.id.toString(),
        username: clientOptions.username,
      };
      if (clientOptions.email) {
        profile.emails = [{ value: clientOptions.email }];
      }
      if (clientOptions.avatar) {
        profile.photos = [{ value: clientOptions.avatar }];
      }
      if (clientOptions.locale) {
        profile.locale = clientOptions.locale;
      }
      return profile;
    } else {
      if (!clientOptions.username || !clientOptions.password) return this.app.throw(401);
      // user
      const user = await this.bean.user.findOneByName(clientOptions.username);
      if (!user) return this.app.throw(401);
      // verify
      const profileId = await this.scope.service.authSimple.verifyPassword(user.id, clientOptions.password);
      if (!profileId) return this.app.throw(401);
      // profile
      const profile: IAuthUserProfile = {
        id: profileId.toString(),
      };
      return profile;
    }
  }
}IAuthProviderSimpleClientRecord: Defines multiple Clients, with a default definition fordefaultIAuthProviderSimpleClientOptions: Defines Client optionsIAuthProviderOptionsSimple: Defines the parameters of the Auth Providerverify: Processesregisterandlogin, returning Profile data
Profile 
- The Provider's 
verifyonly needs to return Profile data. The system will generate a User object based on the Profile data - Both 
registerandloginmust return the sameidfield value - Ensure that a unique 
idvalue is generated for each user 
Profile has a unified interface definition:
typescript
export interface IAuthUserProfile {
  id: string;
  username?: string;
  displayName?: string;
  name?: IAuthUserProfileName;
  gender?: string; // male/female
  profileUrl?: string;
  emails?: IAuthUserProfilePropSlice[];
  photos?: IAuthUserProfilePropSlice[];
  locale?: keyof ILocaleInfos;
  confirmed?: boolean;
}confirmed: Iftrue, it means the user has confirmed and no furtheractivationoperation is needed