- Prerequisites
- Steps
- Initialise a New Graphweaver Project
- Install Dependencies
- Get Sample Database
- Import Database Schema
- Create Credentials Table
- Define the Credential Entity
- Create Auth Connection
- Initialise Authentication Environment
- Starting Graphweaver
- Next Steps
In this guide, we'll walk through setting up password authentication for your Graphweaver project.
This guide will also use an Sqlite database as an example data provider. Feel free to follow along or replace with your own data source as needed.
Let’s get started.
Prerequisites
- Node.js and npm/pnpm: Make sure you have Node.js 20 or above along with npm and pnpm (8+) installed on your system.
- Some of the commands use
curl
andsqlite3
from the command line. These can be substituted with your own tools if you do not have them
Steps
Initialise a New Graphweaver Project
npx graphweaver@latest init
- You'll be prompted to name your project (e.g., passwordExample ).
- For this example choose the "Mikro-orm Sqlite backend". However, if you have a different datasource then use that.
- Confirm the creation of the new Graphweaver app.
Install Dependencies
cd passwordExample
pnpm add @exogee/graphweaver-auth @exogee/graphweaver-auth-ui-components @exogee/graphweaver-admin-ui-components
This installs:
@exogee/graphweaver-auth
: Core Graphweaver authentication package used in the backend.@exogee/graphweaver-auth-ui-components
: Pre-built UI components for login/logout these are used by the AdminUI.@exogee/graphweaver-admin-ui-components
: The components used by the AdminUI.
Get Sample Database
Next, lets download the sample database:
curl -L -o database.sqlite https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite
- This downloads a sample SQLite database named 'Chinook_Sqlite.sqlite' and renames it to 'database.sqlite'. We'll use this to store user credentials.
Import Database Schema
Next, we can introspect the database schema which will create the Graphweaver source files.
pnpm run import sqlite
What is the database name? database.sqlite
Overwrite this file backend/schema/index.ts? yes
Overwrite this file backend/database.ts? yes
- This command analyzes the SQLite database and generates TypeScript code representing its schema.
- It overwrites existing
backend/schema/index.ts
andbackend/database.ts
files to integrate the new database structure into your Graphweaver project.
Create Credentials Table
Next, let’s add a new table to the database to store our credentials:
sqlite3 ./database.sqlite "CREATE TABLE Credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username NVARCHAR(255) NOT NULL UNIQUE,
password NVARCHAR(255) NOT NULL
);"
- This directly interacts with the SQLite database to create a table named 'Credentials.'
- This table will store user login information:
- 'id': A unique identifier for each user.
- 'username': The username for login.
- 'password': The hashed password for the user.
Define the Credential 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/credential.ts
with this contents:
touch ./src/backend/entities/sqlite/credential.ts
import { BigIntType, Entity, PrimaryKey, Property } from "@mikro-orm/core";
import { CredentialStorage } from "@exogee/graphweaver-auth";
@Entity({ tableName: "Credentials" })
export class Credential implements CredentialStorage {
@PrimaryKey({ type: new BigIntType("string") })
id!: string;
@Property({ type: String })
username!: string;
@Property({ type: String })
password!: string;
}
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 { Credential } from "./credential";
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 "./credential";
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,
Credential,
Customer,
Employee,
Genre,
Invoice,
InvoiceLine,
MediaType,
Playlist,
Track,
];
Create Auth Connection
In order to enable password authentication in the app we need to add the following to our ./src/backend/index.ts
:
/* password Graphweaver Project */
import Graphweaver from "@exogee/graphweaver-server";
import "./schema";
import {
UserProfile,
Password,
setAddUserToContext,
} from "@exogee/graphweaver-auth";
import { MikroBackendProvider } from "@exogee/graphweaver-mikroorm";
import { Credential as OrmCredential } from "./entities/sqlite";
import { connection } from "./database";
export const addUserToContext = async (userId: string) => {
return new UserProfile({
id: userId,
roles: ["everyone"],
});
};
setAddUserToContext(addUserToContext);
export const password = new Password({
provider: new MikroBackendProvider(OrmCredential, connection),
acl: {
Everyone: {
all: true,
},
},
getUserProfile: async (id: string): Promise<UserProfile<string>> => {
return addUserToContext(id);
},
});
export const graphweaver = new Graphweaver();
export const handler = graphweaver.handler();
This code sets up the core password integration in your backend:
- It imports necessary modules from
@exogee/graphweaver-auth
. - It creates an
Password
instance to handle login interactions. - The
addUserToContext
function defines how to map the logged in userId to a basic user profile when a user logs in. You can customise this to fetch additional user data from any data store. setAddUserToContext
configures Graphweaver to use youraddUserToContext
function to retrieve user information and add it to the GraphQL context.
Initialise Authentication Environment
There are a few extra files needed when setting up authentication. This includes an environment variable file and a graphweaver-config.js
file.
These are a bit tricky to setup at first but luckily for us there is a command line tool that can help.
This command line tool will also create the admin user for us and generate a random password.
To run it:
pnpm graphweaver init-auth
? What is the data source? sqlite
? What is the database name? database.sqlite
? Please specify the exact name of the table where you would like the credentials to be stored: Credentials
****************************************
****** Admin Password: YOUR_PASSWORD_WILL_BE_HERE ******
****************************************
- This command sets up the authentication system within Graphweaver:
- Generates an
.env
file with new keys used to sign JWT tokens - Configures Graphweaver and creates a new
graphweaver-config.js
file. - Connects to your database and creates a new random password, saving a hash to the database. The username for this password is
admin
.
Starting Graphweaver
You've successfully set up password authentication in your Graphweaver project!
Let’s start the server and login:
Remember to use your login password that we created in the previous step with the username admin
.
Next Steps
- Customise User Profiles: The
addUserToContext
function is a basic example. You'll likely want to fetch additional user information (e.g., email, name) and store it in your database. - Permissions and Authorisation: There are currently only an ACL for the password credentials is a starting point. You'll need to implement proper authorisation rules to control what different users can do in your app.