Skip to content

fix: definitions for accountLockout and passwordPolicy #7040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions resources/buildConfigDefinitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,17 @@ function getCommentValue(comment) {
}

function getENVPrefix(iface) {
if (iface.id.name === 'ParseServerOptions') {
return 'PARSE_SERVER_';
const options = {
'ParseServerOptions' : 'PARSE_SERVER_',
'CustomPagesOptions' : 'PARSE_SERVER_CUSTOM_PAGES_',
'LiveQueryServerOptions' : 'PARSE_LIVE_QUERY_SERVER_',
'LiveQueryOptions' : 'PARSE_SERVER_LIVEQUERY_',
'IdempotencyOptions' : 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_',
'AccountLockoutOptions' : 'PARSE_SERVER_ACCOUNT_LOCKOUT_',
'PasswordPolicyOptions' : 'PARSE_SERVER_PASSWORD_POLICY_'
}
if (iface.id.name === 'CustomPagesOptions') {
return 'PARSE_SERVER_CUSTOM_PAGES_';
}
if (iface.id.name === 'LiveQueryServerOptions') {
return 'PARSE_LIVE_QUERY_SERVER_';
}
if (iface.id.name === 'LiveQueryOptions') {
return 'PARSE_SERVER_LIVEQUERY_';
}
if (iface.id.name === 'IdempotencyOptions') {
return 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_';
if (options[iface.id.name]) {
return options[iface.id.name]
}
}

Expand Down
51 changes: 49 additions & 2 deletions src/Options/Definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ module.exports.ParseServerOptions = {
},
emailVerifyTokenReuseIfValid: {
env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_REUSE_IF_VALID',
help:
'an existing email verify token should be reused when resend verification email is requested',
help: 'an existing email verify token should be reused when resend verification email is requested',
action: parsers.booleanParser,
default: false,
},
Expand Down Expand Up @@ -552,3 +551,51 @@ module.exports.IdempotencyOptions = {
default: 300,
},
};
module.exports.AccountLockoutOptions = {
duration: {
env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_DURATION',
help:
'number of minutes that a locked-out account remains locked out before automatically becoming unlocked.',
action: parsers.numberParser('duration'),
},
threshold: {
env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_THRESHOLD',
help: 'number of failed sign-in attempts that will cause a user account to be locked',
action: parsers.numberParser('threshold'),
},
};
module.exports.PasswordPolicyOptions = {
doNotAllowUsername: {
env: 'PARSE_SERVER_PASSWORD_POLICY_DO_NOT_ALLOW_USERNAME',
help: 'disallow username in passwords',
action: parsers.booleanParser,
},
maxPasswordAge: {
env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_AGE',
help: 'days for password expiry',
action: parsers.numberParser('maxPasswordAge'),
},
maxPasswordHistory: {
env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_HISTORY',
help: 'setting to prevent reuse of previous n passwords',
action: parsers.numberParser('maxPasswordHistory'),
},
resetTokenReuseIfValid: {
env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID',
help: "resend token if it's still valid",
action: parsers.booleanParser,
},
resetTokenValidityDuration: {
env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_VALIDITY_DURATION',
help: 'time for token to expire',
action: parsers.numberParser('resetTokenValidityDuration'),
},
validatorCallback: {
env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_CALLBACK',
help: 'a callback function to be invoked to validate the password',
},
validatorPattern: {
env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_PATTERN',
help: 'a RegExp object or a regex string representing the pattern to enforce',
},
};
21 changes: 19 additions & 2 deletions src/Options/docs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @interface ParseServerOptions
* @property {Any} accountLockout account lockout policy for failed login attempts
* @property {AccountLockoutOptions} accountLockout account lockout policy for failed login attempts
* @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true
* @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId
* @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers
Expand Down Expand Up @@ -53,7 +53,7 @@
* @property {String} mountPath Mount path for the server, defaults to /parse
* @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production
* @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10
* @property {Any} passwordPolicy Password policy for enforcing password related rules
* @property {PasswordPolicyOptions} passwordPolicy Password policy for enforcing password related rules
* @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground
* @property {Number} port The port to run the ParseServer, defaults to 1337.
* @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names
Expand Down Expand Up @@ -120,3 +120,20 @@
* @property {String[]} paths An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths.
* @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s.
*/

/**
* @interface AccountLockoutOptions
* @property {Number} duration number of minutes that a locked-out account remains locked out before automatically becoming unlocked.
* @property {Number} threshold number of failed sign-in attempts that will cause a user account to be locked
*/

/**
* @interface PasswordPolicyOptions
* @property {Boolean} doNotAllowUsername disallow username in passwords
* @property {Number} maxPasswordAge days for password expiry
* @property {Number} maxPasswordHistory setting to prevent reuse of previous n passwords
* @property {Boolean} resetTokenReuseIfValid resend token if it's still valid
* @property {Number} resetTokenValidityDuration time for token to expire
* @property {Function} validatorCallback a callback function to be invoked to validate the password
* @property {String} validatorPattern a RegExp object or a regex string representing the pattern to enforce
*/
28 changes: 26 additions & 2 deletions src/Options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ export interface ParseServerOptions {
:DEFAULT: false */
emailVerifyTokenReuseIfValid: ?boolean;
/* account lockout policy for failed login attempts */
accountLockout: ?any;
accountLockout: ?AccountLockoutOptions;
/* Password policy for enforcing password related rules */
passwordPolicy: ?any;
passwordPolicy: ?PasswordPolicyOptions;
/* Adapter module for the cache */
cacheAdapter: ?Adapter<CacheAdapter>;
/* Adapter module for email sending */
Expand Down Expand Up @@ -291,3 +291,27 @@ export interface IdempotencyOptions {
:DEFAULT: 300 */
ttl: ?number;
}

export interface AccountLockoutOptions {
/* number of minutes that a locked-out account remains locked out before automatically becoming unlocked. */
duration: ?number;
/* number of failed sign-in attempts that will cause a user account to be locked */
threshold: ?number;
}

export interface PasswordPolicyOptions {
/* a RegExp object or a regex string representing the pattern to enforce */
validatorPattern: ?string;
/* a callback function to be invoked to validate the password */
validatorCallback: ?() => void;
/* disallow username in passwords */
doNotAllowUsername: ?boolean;
/* days for password expiry */
maxPasswordAge: ?number;
/* setting to prevent reuse of previous n passwords */
maxPasswordHistory: ?number;
/* time for token to expire */
resetTokenValidityDuration: ?number;
/* resend token if it's still valid */
resetTokenReuseIfValid: ?boolean;
}