# Create user
The script will be executed when the user registers or creates a user using the API and console. You need to save the user information in your own database. This script is only required in full use of the custom database schema.
# Function definition
The createUser
function is defined as follows:
async function createUser(userinfo, context) {
// This script should create a user entry in your existing database. It will
// be executed when a user attempts to sign up, or when a user is created
// through the Auth0 dashboard or API.
// When this script has finished executing, the Login script will be
// executed immediately afterwards, to verify that the user was created
// successfully.
// The first argument userinfo contains following properties:
// * email: the user's email
// * username: the user's username
// * phone: the user's phone number
// * password: the user's password in plain text format
// * nickname: the user's nickname
// * photo: the user's photo
// The Second argument context contains information about the authentication context.
// see http://core.authing.cn/connections/custom-db/config-custom-db-connection.html for more information.
//
// There are three ways this script can finish:
// 1. A user was successfully created
// format: https://docs.authing.co/user/profile.html.
// return null
// 2. This user already exists in your database
// throw new Error("user allready exists")
// 3. Something went wrong while trying to reach your database:
// throw new Error("my error message")
const msg =
'Please implement the Find User script for this database connection';
throw new Error(msg);
}
Parameters | Type | nullable | Description |
---|---|---|---|
userinfo | object | false | Query conditions |
userinfo.email | string | ture | Email, this parameter may be empty. |
userinfo.phone | string | true | Mobile phone number, this parameter may be empty. |
userinfo.username | string | true | Username, this parameter may be empty. |
userinfo.password | string | true | Clear text password. This parameter may be empty. It is strongly recommended to use bcrypt to encrypt user passwords. See below for details. |
userinfo.nickname | string | true | User nickname, this parameter may be empty. |
userinfo.photo | string | true | User profile picture, this parameter may be empty. |
context | object | true | request context context |
The context contains the following information:
Property name | Type | Description |
---|---|---|
userPoolId | string | User Pool ID |
userPoolName | string | User pool name |
userPoolMetadata | object | User pool configuration information |
appId | string | ID of the current user, **You can distinguish the source of the application requested by the user through appId. ** |
appName | string | The name of the current application |
appMetadata | object | Current application configuration information |
application | string | User Pool ID |
request | object | The detailed information of the current request, including: ip : client IP geo : client geographic location resolved by IP body : request body |
# Return data convention
# Created successfully
When the user is successfully created, you need to return the user information of the user to Authing. For the detailed format of the user information, please see: User Profile Field. Example:
async function getUser(userinfo, context) {
// Implement your logic here
return {
id: 1, // must not empty
email: "test@example.com",
emailVerified: true,
nickname: "Nick",
photo: ""
}
}
# User already exists
When the user already exists, you need to throw an error directly (the error message can be freely defined), for example:
async function login(query, password, context) {
// Implement your logic here
throw new Error('User allready exists!');
}
# Other exception errors
When encountering other abnormal errors, you can catch the error and return a more friendly error prompt, for example:
async function getUser(userinfo, context) {
try {
// Implement your logic here
} catch (error) {
throw new Error('Something went wrong ...')
}
}
# Best Practices
# Provide friendly error tips
When encountering an unknown error, we recommend throwing a standard Error
object. Authing will catch this error and return it to the end user. For example: throw new Error("My nice error message")
, you can see the error log in the log history of the custom database.
# Disconnect the database connection at the end of the function
Please remember to close the connection to the database when the script is executed, such as calling client.end(). For example, it can be executed in try/finalllyMake sure it will always be executed:
try {
const result = await client.userinfo("YOUR userinfo");
} finally {
// NOTE: always call `client.end()` here to close the connection to the database
client.end();
}
# Example function
Taking the postgres
database as an example, the following points are explained:
-You can get the database connection string through env.DB_CONNECTION_URI
to create a database connection.
-Dynamically create query statements based on the query conditions passed in userinfo
(userinfo.id
, userinfo.email
, userinfo.username
, userinfo.phone
may all be empty, but not at the same time ).
-First check whether the user exists. If the user exists, an exception will be thrown. The error message is: User allready exists!
.
-Finally, the user information in the specified format is returned. For the detailed format of the user information, please see: User Profile Field.
-Call client.end()
in try/finally
to disconnect the database.
async function createUser(userinfo, context) {
// get exist user from database
const queryUser = async (client, query) => {
const {email, phone, username} = query;
// Build query parameters
const queries = [];
const parameters = [];
let index = 1;
if (email) {
queries.push(`email = $${index}`);
parameters.push(email);
index += 1;
}
if (phone) {
queries.push(`phone = $${index}`);
parameters.push(phone);
index += 1;
}
if (username) {
queries.push(`username = $${index}`);
parameters.push(username);
index += 1;
}
const QUERY = `SELECT * FROM users WHERE ${queries.join(' OR')} LIMIT 1`;
const result = await client.query(QUERY, parameters);
return result;
};
// This example uses the "pg" library
// more info here: https://github.com/brianc/node-postgres
const {Client} = require('pg');
const client = new Client({
connectionString: env.DB_CONNECTION_URI,
});
// Or you can:
// const client = new Client({
// host: env.DB_HOST,
// port: env.DB_PORT,
// user: env.DB_USERNAME,
// password: env.DB_PASSWORD,
// database: env.DB_DATABASE,
// });
await client.connect();
try {
const findResult = await queryUser(client, {
email: userinfo.email,
phone: userinfo.phone,
username: userinfo.username,
});
if (findResult.rows.length> 0) {
throw new Error('User allready exists!');
}
// Use bcrypt to encrypt password
// more info here: https://github.com/kelektiv/node.bcrypt.js
const bcrypt = require('bcrypt');
let hashedPassword = null;
// Phone Code Login may not have a password
if (userinfo.password) {
hashedPassword = await bcrypt.hash(
userinfo.password,
await bcrypt.genSalt(10),
);
}
const insertResult = await client.query(
`INSERT INTO users(email, username, phone, password, nickname, photo) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`,
[
userinfo.email,
userinfo.username,
userinfo.phone,
hashedPassword,
userinfo.nickname,
userinfo.photo,
],
);
const user = insertResult.rows[0];
return {
id: user.id,
email: user.email,
name: user.name,
phone: user.phone,
username: user.username,
photo: user.photo,
nickname: user.nickname,
token: user.token,
emailVerified: user.email_verified,
phoneVerified: user.phone_verified,
loginsCount: user.logins_count,
lastIp: user.last_ip,
gender: user.gender,
address: user.address,
company: user.company,
birthdate: user.birthdate,
website: user.website,
};
} catch (error) {
throw new Error(`Execute query failed: ${error.message}`);
} finally {
// NOTE: always call `client.end()` here to close the connection to the database
client.end();
}
}
â Get User Modify user information â