mirror of
https://github.com/vale981/accounts-ui
synced 2025-03-04 17:31:41 -05:00
236 lines
7.6 KiB
JavaScript
236 lines
7.6 KiB
JavaScript
import { Accounts } from 'meteor/accounts-base';
|
|
import {
|
|
redirect,
|
|
validatePassword,
|
|
validateEmail,
|
|
validateUsername,
|
|
} from './helpers.js';
|
|
|
|
/**
|
|
* @summary Accounts UI
|
|
* @namespace
|
|
* @memberOf Accounts
|
|
*/
|
|
Accounts.ui = {};
|
|
|
|
Accounts.ui._options = {
|
|
requestPermissions: [],
|
|
requestOfflineToken: {},
|
|
forceApprovalPrompt: {},
|
|
requireEmailVerification: false,
|
|
passwordSignupFields: 'EMAIL_ONLY_NO_PASSWORD',
|
|
minimumPasswordLength: 7,
|
|
loginPath: '/',
|
|
signUpPath: null,
|
|
resetPasswordPath: null,
|
|
profilePath: '/',
|
|
changePasswordPath: null,
|
|
homeRoutePath: '/',
|
|
onSubmitHook: () => {},
|
|
onPreSignUpHook: () => new Promise(resolve => resolve()),
|
|
onPostSignUpHook: () => {},
|
|
onEnrollAccountHook: () => redirect(`${Accounts.ui._options.loginPath}`),
|
|
onResetPasswordHook: () => redirect(`${Accounts.ui._options.loginPath}`),
|
|
onVerifyEmailHook: () => redirect(`${Accounts.ui._options.profilePath}`),
|
|
onSignedInHook: () => redirect(`${Accounts.ui._options.homeRoutePath}`),
|
|
onSignedOutHook: () => redirect(`${Accounts.ui._options.homeRoutePath}`),
|
|
emailPattern: new RegExp('[^@]+@[^@\.]{2,}\.[^\.@]+'),
|
|
};
|
|
|
|
/**
|
|
* @summary Configure the behavior of [`<Accounts.ui.LoginForm />`](#react-accounts-ui).
|
|
* @anywhere
|
|
* @param {Object} options
|
|
* @param {Object} options.requestPermissions Which [permissions](#requestpermissions) to request from the user for each external service.
|
|
* @param {Object} options.requestOfflineToken To ask the user for permission to act on their behalf when offline, map the relevant external service to `true`. Currently only supported with Google. See [Meteor.loginWithExternalService](#meteor_loginwithexternalservice) for more details.
|
|
* @param {Object} options.forceApprovalPrompt If true, forces the user to approve the app's permissions, even if previously approved. Currently only supported with Google.
|
|
* @param {String} options.passwordSignupFields Which fields to display in the user creation form. One of '`USERNAME_AND_EMAIL`', '`USERNAME_AND_OPTIONAL_EMAIL`', '`USERNAME_ONLY`', '`EMAIL_ONLY`', or '`NO_PASSWORD`' (default).
|
|
*/
|
|
Accounts.ui.config = function(options) {
|
|
// validate options keys
|
|
const VALID_KEYS = [
|
|
'passwordSignupFields',
|
|
'requestPermissions',
|
|
'requestOfflineToken',
|
|
'forbidClientAccountCreation',
|
|
'requireEmailVerification',
|
|
'minimumPasswordLength',
|
|
'loginPath',
|
|
'signUpPath',
|
|
'resetPasswordPath',
|
|
'profilePath',
|
|
'changePasswordPath',
|
|
'homeRoutePath',
|
|
'onSubmitHook',
|
|
'onPreSignUpHook',
|
|
'onPostSignUpHook',
|
|
'onEnrollAccountHook',
|
|
'onResetPasswordHook',
|
|
'onVerifyEmailHook',
|
|
'onSignedInHook',
|
|
'onSignedOutHook',
|
|
'validateField',
|
|
'emailPattern',
|
|
];
|
|
|
|
Object.keys(options).forEach(function (key) {
|
|
if (!VALID_KEYS.includes(key))
|
|
throw new Error("Accounts.ui.config: Invalid key: " + key);
|
|
});
|
|
|
|
// Deal with `passwordSignupFields`
|
|
if (options.passwordSignupFields) {
|
|
if ([
|
|
"USERNAME_AND_EMAIL",
|
|
"USERNAME_AND_OPTIONAL_EMAIL",
|
|
"USERNAME_ONLY",
|
|
"EMAIL_ONLY",
|
|
"EMAIL_ONLY_NO_PASSWORD",
|
|
"USERNAME_AND_EMAIL_NO_PASSWORD"
|
|
].includes(options.passwordSignupFields)) {
|
|
Accounts.ui._options.passwordSignupFields = options.passwordSignupFields;
|
|
}
|
|
else {
|
|
throw new Error("Accounts.ui.config: Invalid option for `passwordSignupFields`: " + options.passwordSignupFields);
|
|
}
|
|
}
|
|
|
|
// Deal with `requestPermissions`
|
|
if (options.requestPermissions) {
|
|
Object.keys(options.requestPermissions).forEach(service => {
|
|
const scope = options.requestPermissions[service];
|
|
if (Accounts.ui._options.requestPermissions[service]) {
|
|
throw new Error("Accounts.ui.config: Can't set `requestPermissions` more than once for " + service);
|
|
}
|
|
else if (!(scope instanceof Array)) {
|
|
throw new Error("Accounts.ui.config: Value for `requestPermissions` must be an array");
|
|
}
|
|
else {
|
|
Accounts.ui._options.requestPermissions[service] = scope;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Deal with `requestOfflineToken`
|
|
if (options.requestOfflineToken) {
|
|
Object.keys(options.requestOfflineToken).forEach(service => {
|
|
const value = options.requestOfflineToken[service];
|
|
if (service !== 'google')
|
|
throw new Error("Accounts.ui.config: `requestOfflineToken` only supported for Google login at the moment.");
|
|
|
|
if (Accounts.ui._options.requestOfflineToken[service]) {
|
|
throw new Error("Accounts.ui.config: Can't set `requestOfflineToken` more than once for " + service);
|
|
}
|
|
else {
|
|
Accounts.ui._options.requestOfflineToken[service] = value;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Deal with `forceApprovalPrompt`
|
|
if (options.forceApprovalPrompt) {
|
|
Object.keys(options.forceApprovalPrompt).forEach(service => {
|
|
const value = options.forceApprovalPrompt[service];
|
|
if (service !== 'google')
|
|
throw new Error("Accounts.ui.config: `forceApprovalPrompt` only supported for Google login at the moment.");
|
|
|
|
if (Accounts.ui._options.forceApprovalPrompt[service]) {
|
|
throw new Error("Accounts.ui.config: Can't set `forceApprovalPrompt` more than once for " + service);
|
|
}
|
|
else {
|
|
Accounts.ui._options.forceApprovalPrompt[service] = value;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Deal with `requireEmailVerification`
|
|
if (options.requireEmailVerification) {
|
|
if (typeof options.requireEmailVerification != 'boolean') {
|
|
throw new Error(`Accounts.ui.config: "requireEmailVerification" not a boolean`);
|
|
}
|
|
else {
|
|
Accounts.ui._options.requireEmailVerification = options.requireEmailVerification;
|
|
}
|
|
}
|
|
|
|
// Deal with `minimumPasswordLength`
|
|
if (options.minimumPasswordLength) {
|
|
if (typeof options.minimumPasswordLength != 'number') {
|
|
throw new Error(`Accounts.ui.config: "minimumPasswordLength" not a number`);
|
|
}
|
|
else {
|
|
Accounts.ui._options.minimumPasswordLength = options.minimumPasswordLength;
|
|
}
|
|
}
|
|
|
|
// Deal with the hooks.
|
|
for (let hook of [
|
|
'onSubmitHook',
|
|
'onPreSignUpHook',
|
|
'onPostSignUpHook',
|
|
]) {
|
|
if (options[hook]) {
|
|
if (typeof options[hook] != 'function') {
|
|
throw new Error(`Accounts.ui.config: "${hook}" not a function`);
|
|
}
|
|
else {
|
|
Accounts.ui._options[hook] = options[hook];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Deal with pattern.
|
|
for (let hook of [
|
|
'emailPattern',
|
|
]) {
|
|
if (options[hook]) {
|
|
if (!(options[hook] instanceof RegExp)) {
|
|
throw new Error(`Accounts.ui.config: "${hook}" not a Regular Expression`);
|
|
}
|
|
else {
|
|
Accounts.ui._options[hook] = options[hook];
|
|
}
|
|
}
|
|
}
|
|
|
|
// deal with the paths.
|
|
for (let path of [
|
|
'loginPath',
|
|
'signUpPath',
|
|
'resetPasswordPath',
|
|
'profilePath',
|
|
'changePasswordPath',
|
|
'homeRoutePath'
|
|
]) {
|
|
if (typeof options[path] !== 'undefined') {
|
|
if (options[path] !== null && typeof options[path] !== 'string') {
|
|
throw new Error(`Accounts.ui.config: ${path} is not a string or null`);
|
|
}
|
|
else {
|
|
Accounts.ui._options[path] = options[path];
|
|
}
|
|
}
|
|
}
|
|
|
|
// deal with redirect hooks.
|
|
for (let hook of [
|
|
'onEnrollAccountHook',
|
|
'onResetPasswordHook',
|
|
'onVerifyEmailHook',
|
|
'onSignedInHook',
|
|
'onSignedOutHook']) {
|
|
if (options[hook]) {
|
|
if (typeof options[hook] == 'function') {
|
|
Accounts.ui._options[hook] = options[hook];
|
|
}
|
|
else if (typeof options[hook] == 'string') {
|
|
Accounts.ui._options[hook] = () => redirect(options[hook]);
|
|
}
|
|
else {
|
|
throw new Error(`Accounts.ui.config: "${hook}" not a function or an absolute or relative path`);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
export default Accounts;
|