packages/accounts-ui-unstyled/accounts_ui.js
/**
* @summary Accounts UI
* @namespace
* @memberOf Accounts
* @importFromPackage accounts-base
*/
Accounts.ui = {
_options: {
requestPermissions: Object.create(null),
requestOfflineToken: Object.create(null),
forceApprovalPrompt: Object.create(null),
},
};
const VALID_OPTIONS = new Set()
.add('passwordSignupFields')
.add('requestPermissions')
.add('requestOfflineToken')
.add('forceApprovalPrompt')
.add('passwordlessSignupFields');
const VALID_PASSWORD_SIGNUP_FIELDS = new Set()
.add('USERNAME_AND_EMAIL')
.add('USERNAME_AND_OPTIONAL_EMAIL')
.add('USERNAME_ONLY')
.add('EMAIL_ONLY');
function isValidPasswordSignupField(field) {
return VALID_PASSWORD_SIGNUP_FIELDS.has(field);
}
const VALID_PASSWORDLESS_SIGNUP_FIELDS = new Set()
.add('USERNAME_AND_EMAIL')
.add('EMAIL_ONLY');
function isValidPasswordlessSignupField(field) {
return VALID_PASSWORDLESS_SIGNUP_FIELDS.has(field);
}
/**
* @summary Configure the behavior of [`{{> loginButtons}}`](#accountsui).
* @locus Client
* @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`', or '`EMAIL_ONLY`' (default).
* @param {String} options.passwordlessSignupFields Which fields to display in the user creation form. One of '`USERNAME_AND_EMAIL`', '`EMAIL_ONLY`' (default).
* @importFromPackage accounts-base
*/
Accounts.ui.config = options => {
Object.keys(options).forEach(key => {
if (!VALID_OPTIONS.has(key)) {
throw new Error(`Accounts.ui.config: Invalid option: ${key}`);
}
});
handlePasswordSignupFields(options);
handlePasswordlessSignupFields(options);
handleRequestPermissions(options);
handleRequestOfflineToken(options);
handleForceApprovalPrompt(options);
};
Meteor.startup(function() {
const settings = Meteor.settings.public?.packages?.['accounts-ui-unstyled'];
if (settings) {
Accounts.ui.config(settings);
}
});
function handlePasswordlessSignupFields(options) {
let { passwordlessSignupFields } = options;
if (passwordlessSignupFields) {
const reportInvalid = () => {
throw new Error(
`Accounts.ui.config: Invalid option for \`passwordlessSignupFields\`: ${passwordlessSignupFields}`
);
};
if (typeof passwordlessSignupFields === 'string') {
passwordlessSignupFields = [passwordlessSignupFields];
} else if (!Array.isArray(passwordlessSignupFields)) {
reportInvalid();
}
if (passwordlessSignupFields.every(isValidPasswordlessSignupField)) {
if (Accounts.ui._options.passwordlessSignupFields) {
throw new Error(
"Accounts.ui.config: Can't set `passwordlessSignupFields` more than once"
);
}
Object.assign(Accounts.ui._options, { passwordlessSignupFields });
return;
}
reportInvalid();
}
}
function handlePasswordSignupFields(options) {
let { passwordSignupFields } = options;
if (passwordSignupFields) {
const reportInvalid = () => {
throw new Error(
`Accounts.ui.config: Invalid option for \`passwordSignupFields\`: ${passwordSignupFields}`
);
};
if (typeof passwordSignupFields === 'string') {
passwordSignupFields = [passwordSignupFields];
} else if (!Array.isArray(passwordSignupFields)) {
reportInvalid();
}
if (passwordSignupFields.every(isValidPasswordSignupField)) {
if (Accounts.ui._options.passwordSignupFields) {
throw new Error(
"Accounts.ui.config: Can't set `passwordSignupFields` more than once"
);
}
Object.assign(Accounts.ui._options, { passwordSignupFields });
return;
}
reportInvalid();
}
}
export function passwordSignupFields() {
const { passwordSignupFields } = Accounts.ui._options;
if (Array.isArray(passwordSignupFields)) {
return passwordSignupFields;
}
if (typeof passwordSignupFields === 'string') {
return [passwordSignupFields];
}
return ['EMAIL_ONLY'];
}
export function passwordlessSignupFields() {
const { passwordlessSignupFields } = Accounts.ui._options;
if (Array.isArray(passwordlessSignupFields)) {
return passwordlessSignupFields;
}
if (typeof passwordlessSignupFields === 'string') {
return [passwordlessSignupFields];
}
return ['EMAIL_ONLY'];
}
function handleRequestPermissions({ requestPermissions }) {
if (requestPermissions) {
Object.keys(requestPermissions).forEach(service => {
if (Accounts.ui._options.requestPermissions[service]) {
throw new Error(
`Accounts.ui.config: Can't set \`requestPermissions\` more than once for ${service}`
);
}
const scope = requestPermissions[service];
if (!Array.isArray(scope)) {
throw new Error(
'Accounts.ui.config: Value for `requestPermissions` must be an array'
);
}
Accounts.ui._options.requestPermissions[service] = scope;
});
}
}
function handleRequestOfflineToken({ requestOfflineToken }) {
if (requestOfflineToken) {
Object.keys(requestOfflineToken).forEach(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}`
);
}
Accounts.ui._options.requestOfflineToken[service] =
requestOfflineToken[service];
});
}
}
function handleForceApprovalPrompt({ forceApprovalPrompt }) {
if (forceApprovalPrompt) {
Object.keys(forceApprovalPrompt).forEach(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}`
);
}
Accounts.ui._options.forceApprovalPrompt[service] =
forceApprovalPrompt[service];
});
}
}