- Authentication Table
- Create Authentication Table
- Define the Authentication Entity
- Secondary Authentication Methods
- Magic Link
- One Time Password
- Web3
- Passkey
As an example on how to use two factor authentication you will need a Graphweaver app. For this page we assume that you have already followed the Adding Password Authentication guide.
This creates a new Graphweaver app that has a connected Sqlite database.
We will need to add a new table to this datasource so let’s look at this next.
Authentication Table
In order to use the secondary authentication methods we need to save information to a data source. As the password example we are using uses Sqlite we will continue with that.
Whichever secondary authentication method you use you will need to create this table.
Create Authentication Table
Next, let’s add a new table to the database to store our magic links:
sqlite3 ./database.sqlite "CREATE TABLE Authentication (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type VARCHAR(255) NOT NULL,
user_id INTEGER NOT NULL,
data TEXT NOT NULL,
created_at DATE DEFAULT (datetime('now','localtime'))
);"
- This directly interacts with the SQLite database to create a table named 'Authentication'
- This table will store magic link information
Define the Authentication Entity
Now that we have added the table in the database we need to tell Graphweaver about it. To do that open the project in your editor and navigate to the ./src/backend/entities/sqlite
directory.
Then create a new file ./src/backend/entities/sqlite/authentication.ts
with this contents:
touch ./src/backend/entities/sqlite/authentication.ts
import {
Entity,
PrimaryKey,
Property,
JsonType,
BigIntType,
} from "@mikro-orm/core";
import type { AuthenticationBaseEntity } from "@exogee/graphweaver-auth";
@Entity({ tableName: "Authentication" })
export class Authentication<T> implements AuthenticationBaseEntity<T> {
@PrimaryKey({ type: new BigIntType("string") })
id!: string;
@Property({ type: String })
type!: string;
@Property({ type: new BigIntType("string") })
userId!: string;
@Property({ type: JsonType })
data!: T;
@Property({ type: Date })
createdAt!: Date;
}
We also need to make sure that the index file (./src/backend/entities/sqlite/index.ts
) is updated to export this file:
import { Album } from "./album";
import { Artist } from "./artist";
import { Authentication } from "./authentication";
import { Customer } from "./customer";
import { Employee } from "./employee";
import { Genre } from "./genre";
import { Invoice } from "./invoice";
import { InvoiceLine } from "./invoice-line";
import { MediaType } from "./media-type";
import { Playlist } from "./playlist";
import { Track } from "./track";
export * from "./album";
export * from "./artist";
export * from "./authentication";
export * from "./customer";
export * from "./employee";
export * from "./genre";
export * from "./invoice";
export * from "./invoice-line";
export * from "./media-type";
export * from "./playlist";
export * from "./track";
export const entities = [
Album,
Artist,
Authentication,
Customer,
Employee,
Genre,
Invoice,
InvoiceLine,
MediaType,
Playlist,
Track,
];
Secondary Authentication Methods
There are a few secondary auth methods that can be configured with Graphweaver. They are:
PASSWORD
- Prompt for the users passwordMAGIC_LINK
- Send a link to the user that they click to authenticateONE_TIME_PASSWORD
- Send a 6 digit code to the end user for verificationWEB3
- Use a Web3 wallet to authenticatePASSKEY
- Use a device key to authenticate
Magic Link
One Time Password
import { OneTimePassword, OneTimePasswordData } from '@exogee/graphweaver-auth';
import { MikroBackendProvider } from '@exogee/graphweaver-mikroorm';
import { Authentication } from '../../entities/mysql';
import { myConnection } from '../../database';
export const oneTimePassword = new OneTimePassword({
provider: new MikroBackendProvider(Authentication<OneTimePasswordData>, myConnection),
sendOTP: async (otp) => {
// In a production system this would email / sms the OTP and you would not log to the console!
console.log(`\n\n ######## One Time Password Code: ${otp.data.code} ######## \n\n`);
return true;
},
});
Web3
import { Web3, AuthenticationMethod, WalletAddress } from '@exogee/graphweaver-auth';
import { MikroBackendProvider } from '@exogee/graphweaver-mikroorm';
import { Authentication } from '../../entities/mysql';
import { myConnection } from '../../database';
export const web3 = new Web3({
provider: new MikroBackendProvider(Authentication<WalletAddress>, myConnection),
multiFactorAuthentication: async () => {
return {
Everyone: {
// all users must provide a OTP mfa when saving a wallet address
Write: [{ factorsRequired: 1, providers: [AuthenticationMethod.ONE_TIME_PASSWORD] }],
},
};
},
});
Passkey
import { Passkey, PasskeyData } from '@exogee/graphweaver-auth';
import { MikroBackendProvider } from '@exogee/graphweaver-mikroorm';
import { Authentication } from '../../entities/mysql';
import { myConnection } from '../../database';
export const passkey = new Passkey({
dataProvider: new MikroBackendProvider(Authentication<PasskeyData>, myConnection),
});