@rakered/accounts
An account package for managing user accounts in mongodb.

This project aims to be somewhat compatible with Meteor accounts storage, Except for the email verification tokens, resume tokens, and restrictions on usernames. See the FAQ for more specifics about that subject.
Usage
import init from '@rakered/accounts';
const accounts = init();
await accounts.createUser({ username: 'hunter', password: 'hunter2' });Options can be provided in two ways, passing them as object to init, or by providing them as environment variables.
Options
There are various options available. In development mode, this library does not require a MAIL_URL to be set, instead emails will be logged to console.
Environment Variables
-
MAIL_URL String
The smtp url for the mail server to use.
Optional when running in development mode
-
JWT_SECRET String
The secret to sign the jwt tokens with.
-
EMAIL_FROM String
The email address that’s being used as sender.
Optional if
options.email.fromis provided -
BASE_URL String
The url that will be prefixed to magic urls and provided to the email template.
Optional if
options.email.siteUrlis provided -
SITE_NAME String
The site name that will be provided to the email template.
Optional if
options.email.siteNameis provided -
LOGO_URL String
The url for the logo that will be shown in the email.
Optional if
options.email.logoUrlis provided
Collection
First things first, the database connection. If you don’t specify anything, it will be managed for you with @rakered/mongo. The account system will connect to the MongoDB instance that’s available under process.env.MONGO_URL, and will use the users collection to save and read the documents.
custom collection name
If you just wish to specify a different collection, provide the collection name during initialization.
import init from '@rakered/accounts';
const accounts = init({
collection: 'accounts',
});custom collection instance
If you need more control, it’s also possible to pass in a MongoDB Collection instance to it.
import db from '@rakered/mongo';
import init from '@rakered/accounts';
const accounts = init({
collection: db.users,
});using native MongoDB driver
Or even using a native MongoDB Collection
import { MongoClient } from 'mongodb';
import init from '@rakered/accounts';
const client = await MongoClient.connect(process.env.MONGO_URL);
const db = await client.db();
const accounts = init({
collection: db.collection('users'),
});using Meteor.users collection
When migrating away from Meteor, the rawCollection can be used:
import init from '@rakered/accounts';
const accounts = init({
collection: Meteor.users.rawCollection(),
});This library uses @rakered/email to send emails for email address verification and to send password reset tokens. The address for the smtp server is read from process.env.MAIL_URL, be sure to set it to any valid smtp url.
Provide the following options before you deploy to production. The values are used in the email template, and should be replaced with your own.
import init from '@rakered/accounts';
const accounts = init({
email: {
from: 'noreply@example.com',
siteName: 'Example',
siteUrl: 'https://example.com',
logoUrl: 'https://example.com/logo.png',
},
});Token URLs
When using the email system, it’s likely that you need to configure the token URLs. By default, the URLs are configured to use the format as below, but with https://example.com replaced by the siteUrl that you’ve configured under email. Meaning, the verify-email URL, would default to ${siteUrl}/verify-email/${token}. If this schema matches your needs, there is no need to customize. Otherwise, adjust them to accordingly.
import init from '@rakered/accounts';
const accounts = init({
urls: {
verifyEmail: (token) => `https://example.com/verify-email/${token}`,
enrollAccount: (token) => `https://example.com/enroll-account/${token}`,
resetPassword: (token) => `https://example.com/reset-password/${token}`,
},
});Methods
Methods. This library comes with various methods to manage the accounts.
createUser(options)
Create a new user.
options
Both username as well as email are optional, but one of those must be provided.
-
username String
A unique name for this user. Usernames need to match the same requirements as GitHub usernames.
- may only contain alphanumeric characters and hyphens.
- cannot have multiple consecutive hyphens.
- cannot begin or end with a hyphen.
- has a minimum length of 3 characters
- has a maximum length of 20 characters
In addition to the GitHub requirements, there is also a list of
reservedusernames, that cannot be claimed. Think.wellknown,admin,own,owner,you,yourself, and a bunch more.Lastly, usernames are not only guaranteed to be unique, but also not look-alike. To prevent confusion by end users, It’s not possible to register both
smeijeras well ass-meijer.Optional if
emailis provided -
email String
The user’s email address.
Optional if
usernameis provided -
password String | { digest: String, algorithm: ‘sha-256’ }
Optional - The user’s password. The password should not be send in plain text over the wire. Instead, use @rakered/hash to hash it with sha-256 before sending it to the server. When left out, this function won’t be returning refresh tokens. We assume that no password, means that the user is being invited. Use
sendEnrollmentEmailto let them set their initial password. -
name String Optional - The full name of the user.
-
roles String[]
Optional - A string array with roles that should be assigned. These roles will be included in the request token, enabling permissions checks without database requests.
setUsername(options)
Change a user’s username. Use this instead of updating the database directly. The operation will fail if there is an existing user with a similar looking username, or if the username does not match the conditions as specified under createUser.
options
-
userId String
The ID of the user to update
-
username String
The new username for the user
addEmail(options)
Add an email address for a user. Use this instead of directly updating the database. The operation will fail if there is a different user with the same email address.
options
-
userId String
The ID of the user to update.
-
email String
The new email address for the user
-
verified Boolean
Optional - whether the new email address should be marked as verified. Defaults to false.
removeEmail(options)
Remove an email address for a user. Use this instead of updating the database directly.
options
-
userId String
The ID of the user to update.
-
email String
The email address to remove.
verifyEmail(options)
Marks the user’s email address as verified and returns an access token.
options
-
token String
The token retrieved from the verification URL.
resetPassword(options)
Reset the password for a user using a token received in email.
options
-
token String
The token retrieved from the reset password URL.
-
password String | { digest: String, algorithm: ‘sha-256’ }
A new password for the user. The password should not be send in plain text over the wire. Instead, use @rakered/hash to hash it with sha-256 before sending it to the server.
login(options)
Obtain a refreshToken and accessToken by using password based authentication.
options
-
identity String
The
usernameoremailfrom the user for which the token should be created. -
password String | { digest: String, algorithm: ‘sha-256’ }
The user’s password. The password should not be send in plain text over the wire. Instead, use @rakered/hash to hash it with sha-256 before sending it to the server.
refreshToken(options)
Obtain a fresh refreshToken and accessToken. Note that the current refreshToken is revoked.
options
-
refreshToken String
The current refresh token.
-
accessToken String
The current access token.
revokeToken(options)
Revoke the refreshToken so it can no longer be used to obtain new accessTokens.
options
-
refreshToken String
The token that should be revoked.
-
accessToken String
The current access token.
sendEnrollmentEmail(options)
Send an email with a link the user can use to set their initial password.
options
-
userId String
The id of the user to send email to.
-
email String
Optional. Which address of the user’s to send the email to. This address must be in the user’s
emailslist. Defaults to the first email in the list.
sendVerificationEmail(options)
Send an email with a link the user can use verify their email address.
options
-
userId String
The id of the user to send email to.
-
email String
Optional. Which address of the user’s to send the email to. This address must be in the user’s
emailslist. Defaults to the first unverified email in the list.
sendResetPasswordEmail(options)
Send an email with a link the user can use to reset their password.
options
-
userId String
The id of the user to send email to.
-
email String
Optional. Which address of the user’s to send the email to. This address must be in the user’s
emailslist. Defaults to the first email in the list.
disconnect
Close the database connection. Useful when using accounts in console scripts.
Properties
collection
The MongoDB Collection is exposed under the accounts.collection property, for when you need direct access to the collection.
Good to knows
-
The email verification tokens are incompatible with Meteor, because I’ve taken a different approach there, to limit the database request to a maximum of 1 call per method. The way Meteor manages the verification tokens requires two requests per email verification attempt.
I’ve weighted the pros and cons, and came to the conclusion that a single request outweighs the benefit of Meteor compatibility in this area. In the case where this project is connected to an existing Meteor database, it would be trivial to either migrate the tokens to the format of this project, or to let the user request a new verification token.
To migrate existing tokens, check our migration script example
-
Usernames are more strict than in Meteor, because of this it can be that your existing user collection cannot be used as source for this library. Meteor usernames are case sensitive. Meaning,
alex,Alex, andAleXare different users. We do not support this. We can write a detection script for this, but that’s something we still have to do.