Get User Script Templates
The Get User script implements the function executed to determine the current state of existence of a user. We recommend naming this function getUser
.
This script is required for automatic migration, and conditionally required for legacy authentication depending on the operations configured for the connection.
If automatic migration is configured for the connection, the script is executed whenever the following operations occur:
Login
Password reset
If legacy authentication is configured for the connection, the script is executed whenever the following operations occur:
Create user
Change email
Change password
Password reset
Get User function
The getUser
function should:
Send the user's identifier to the external database's API.
Return the profile data of the user if the user was found.
Return an error if there was an issue determining whether the user exists or not.
Definition
The getUser
function accepts two parameters and returns a callback
function:
getUser(email, callback): function
Was this helpful?
Parameter | Type | Description |
---|---|---|
email |
String | The user's email address. |
callback |
Function | Used to pass error or profile data through the pipeline |
Example
This is a pseudo-Javascript example of how you could implement the getUser
function. For language-specific examples, read Language-specific script examples.
function getUser(email, callback) {
// Send user identifier to external database API
let options = {
url: "https://example.com/api/search-users",
body: {
email: email
}
};
send(options, (err, profileData) => {
// Return error in callback if there was an issue finding the user
if (err) {
return callback(new Error("Could not determine if user exists or not."));
} else {
// Return null in callback if user was not found, return profile data in callback if user was found
if (!profileData) {
return callback(null);
} else {
let profile = {
email: profileData.email
};
return callback(null, profile);
}
}
});
}
Was this helpful?
Callback function
The callback
function is used to pass user profile data or error data through the pipeline.
Definition
The callback
function accepts up to two parameters and returns a function:
callback(error[,profile]): function
Was this helpful?
Parameter | Type | Required | Description |
---|---|---|---|
error |
Object | Required | Contains error data. |
profile |
Object | Optional | Contains the user's profile data. |
Return the user profile (user found)
If the user is found, pass a null
value to the error
parameter, and pass the user's profile data to the profile
parameter in normalized form. In addition to the standard fields, you can include the user_metadata
, app_metadata
, and mfa_factors
fields.
Example
return callback(null, {
username: "username",
user_id: "my-custom-db|username@domain.com",
email: "username@domain.com",
email_verified: false,
user_metadata: {
language: "en"
},
app_metadata: {
plan: "full"
},
mfa_factors: [
{
phone: {
value: "+15551234567"
}
},
]
});
Was this helpful?
Return no user profile (user not found)
If the user is not found, pass a null
value to the error
parameter, and omit the profile
parameter.
Example
return callback(null);
Was this helpful?
Return an error
If an error occurs, pass error data to the error
parameter with relevant information about what went wrong. For more information, read Troubleshoot Custom Databases.
Example
return callback(new Error("My custom error message."));
Was this helpful?
Language-specific script examples
Auth0 provides sample scripts for use with the following languages/technologies:
JavaScript
function getByEmail(email, callback) {
// This script should retrieve a user profile from your existing database,
// without authenticating the user.
// It is used to check if a user exists before executing flows that do not
// require authentication (signup and password reset).
//
// There are three ways this script can finish:
// 1. A user was successfully found. The profile should be in the following
// format: https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.
// callback(null, profile);
// 2. A user was not found
// callback(null);
// 3. Something went wrong while trying to reach your database:
// callback(new Error("my error message"));
const msg = 'Please implement the Get User script for this database connection ' +
'at https://manage.auth0.com/#/connections/database';
return callback(new Error(msg));
}
Was this helpful?
ASP.NET Membership Provider (MVC3 - Universal Providers)
function getByEmail(email, callback) {
const sqlserver = require('tedious@1.11.0');
const Connection = sqlserver.Connection;
const Request = sqlserver.Request;
const TYPES = sqlserver.TYPES;
const connection = new Connection({
userName: 'the username',
password: 'the password',
server: 'the server',
options: {
database: 'the db name',
encrypt: true // for Windows Azure
}
});
connection.on('debug', function(text) {
// if you have connection issues, uncomment this to get more detailed info
//console.log(text);
}).on('errorMessage', function(text) {
// this will show any errors when connecting to the SQL database or with the SQL statements
console.log(JSON.stringify(text));
});
connection.on('connect', function(err) {
if (err) return callback(err);
var user = {};
const query =
'SELECT Memberships.UserId, Email, Users.UserName ' +
'FROM Memberships INNER JOIN Users ' +
'ON Users.UserId = Memberships.UserId ' +
'WHERE Memberships.Email = @Username OR Users.UserName = @Username';
const getMembershipQuery = new Request(query, function(err, rowCount) {
if (err) return callback(err);
if (rowCount < 1) return callback();
callback(null, user);
});
getMembershipQuery.addParameter('Username', TYPES.VarChar, email);
getMembershipQuery.on('row', function(fields) {
user = {
user_id: fields.UserId.value,
nickname: fields.UserName.value,
email: fields.Email.value
};
});
connection.execSql(getMembershipQuery);
});
}
Was this helpful?
ASP.NET Membership Provider (MVC4 - Simple Membership)
function getByEmail(email, callback) {
const sqlserver = require('tedious@1.11.0');
const Connection = sqlserver.Connection;
const Request = sqlserver.Request;
const TYPES = sqlserver.TYPES;
const connection = new Connection({
userName: 'the username',
password: 'the password',
server: 'the server',
options: {
database: 'the db name',
encrypt: true // for Windows Azure
}
});
connection.on('debug', function(text) {
// if you have connection issues, uncomment this to get more detailed info
//console.log(text);
}).on('errorMessage', function(text) {
// this will show any errors when connecting to the SQL database or with the SQL statements
console.log(JSON.stringify(text));
});
connection.on('connect', function(err) {
if (err) return callback(err);
var user = {};
const query =
'SELECT webpages_Membership.UserId, UserName, UserProfile.UserName from webpages_Membership ' +
'INNER JOIN UserProfile ON UserProfile.UserId = webpages_Membership.UserId ' +
'WHERE UserProfile.UserName = @Username';
const getMembershipQuery = new Request(query, function (err, rowCount) {
if (err) return callback(err);
if (rowCount < 1) return callback();
callback(null, user);
});
getMembershipQuery.addParameter('Username', TYPES.VarChar, email);
getMembershipQuery.on('row', function (fields) {
user = {
user_id: fields.UserId.value,
nickname: fields.UserName.value,
email: fields.UserName.value
};
});
connection.execSql(getMembershipQuery);
});
}
Was this helpful?
MongoDB
function getByEmail(email, callback) {
const MongoClient = require('mongodb@3.1.4').MongoClient;
const client = new MongoClient('mongodb://user:pass@mymongoserver.com');
client.connect(function (err) {
if (err) return callback(err);
const db = client.db('db-name');
const users = db.collection('users');
users.findOne({ email: email }, function (err, user) {
client.close();
if (err) return callback(err);
if (!user) return callback(null, null);
return callback(null, {
user_id: user._id.toString(),
nickname: user.nickname,
email: user.email
});
});
});
}
Was this helpful?
MySQL
function getByEmail(email, callback) {
const mysql = require('mysql');
const connection = mysql({
host: 'localhost',
user: 'me',
password: 'secret',
database: 'mydb'
});
connection.connect();
const query = 'SELECT id, nickname, email FROM users WHERE email = ?';
connection.query(query, [ email ], function(err, results) {
if (err || results.length === 0) return callback(err || null);
const user = results[0];
callback(null, {
user_id: user.id.toString(),
nickname: user.nickname,
email: user.email
});
});
}
Was this helpful?
PostgreSQL
function loginByEmail(email, callback) {
//this example uses the "pg" library
//more info here: https://github.com/brianc/node-postgres
const postgres = require('pg');
const conString = 'postgres://user:pass@localhost/mydb';
postgres.connect(conString, function (err, client, done) {
if (err) return callback(err);
const query = 'SELECT id, nickname, email FROM users WHERE email = $1';
client.query(query, [email], function (err, result) {
// NOTE: always call `done()` here to close
// the connection to the database
done();
if (err || result.rows.length === 0) return callback(err);
const user = result.rows[0];
return callback(null, {
user_id: user.id,
nickname: user.nickname,
email: user.email
});
});
});
}
Was this helpful?
SQL Server
function getByEmail(email, callback) {
//this example uses the "tedious" library
//more info here: http://pekim.github.io/tedious/index.html
const sqlserver = require('tedious@1.11.0');
const Connection = sqlserver.Connection;
const Request = sqlserver.Request;
const TYPES = sqlserver.TYPES;
const connection = new Connection({
userName: 'test',
password: 'test',
server: 'localhost',
options: {
database: 'mydb'
}
});
const query = 'SELECT Id, Nickname, Email FROM dbo.Users WHERE Email = @Email';
connection.on('debug', function (text) {
console.log(text);
}).on('errorMessage', function (text) {
console.log(JSON.stringify(text, null, 2));
}).on('infoMessage', function (text) {
console.log(JSON.stringify(text, null, 2));
});
connection.on('connect', function (err) {
if (err) return callback(err);
const request = new Request(query, function (err, rowCount, rows) {
if (err) return callback(err);
callback(null, {
user_id: rows[0][0].value,
nickname: rows[0][1].value,
email: rows[0][2].value
});
});
request.addParameter('Email', TYPES.VarChar, email);
connection.execSql(request);
});
}
Was this helpful?
Windows Azure SQL Database
function getByEmail (name, callback) {
var profile = {
user_id: "103547991597142817347",
nickname: "johnfoo",
email: "johnfoo@gmail.com",
name: "John Foo",
given_name: "John",
family_name: "Foo"
};
callback(null, profile);
}
Was this helpful?
Axios
async function getUserAsync(email, callback) {
//should be updated as new versions of axios are made available (https://auth0-extensions.github.io/canirequire/#axios)
const axios = require("axios@0.22.0");
let response;
try {
response = await axios.post(
//store API url in connection settings to better support SDLC environments
configuration.baseAPIUrl + "/getUser",
//user credentials passed as request body
{
email: email,
},
{
timeout: 10000, //end call gracefully if request times out so script can do necessary callback
headers: {
//securing api call with apiKey stored in connection settings.
//quick and easy approach however using M2M tokens is more secure as
// a secret must not be shared between client and API.
"x-api-key": configuration.apiKey,
},
}
);
} catch (e) {
if (e.response.status === 404) {
//assuming api returns 404 when no user with specified email/username found
return callback(null, null);
}
//callback for any other error type
return callback(new Error(e.message));
}
try {
let user = response.data;
//if using multiple custom db connections in your tenant prefix the
//user_id with a connection specific key ex: "connName|" + user.user_id
//this ensures unique user ids across all db connections
return callback(null, {
user_id: user.user_id,
email: user.email,
});
} catch (e) {
return callback(new Error(e.message));
}
}
Was this helpful?
Stormpath
function getByEmail(email, callback) {
// Replace the {yourStormpathClientId} with your Stormpath ID
var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts';
// Add your Stormpath API Client ID and Secret
var apiCredentials = {
user : '{yourStormpathApiId}',
password: '{yourStormpathApiSecret}'
};
// Make a GET request to find a user by email
request({
url: url,
method: 'GET',
auth: apiCredentials,
qs: { q: email },
json: true
}, function (error, response, body) {
if (response.statusCode !== 200) return callback();
var user = body.items[0];
if (!user) return callback();
var id = user.href.replace('https://api.stormpath.com/v1/accounts/', '');
return callback(null, {
user_id: id,
username: user.username,
email: user.email,
email_verified: true
// Add any additional fields you would like to carry over from Stormpath
});
});
}
Was this helpful?