Skip to content

Commit b6c7907

Browse files
committed
fix: definitions for accountLockout and passwordPolicy
1 parent 4dee0bc commit b6c7907

File tree

4 files changed

+119
-38
lines changed

4 files changed

+119
-38
lines changed

resources/buildConfigDefinitions.js

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,13 @@ function getCommentValue(comment) {
4040
}
4141

4242
function getENVPrefix(iface) {
43-
if (iface.id.name === 'ParseServerOptions') {
44-
return 'PARSE_SERVER_';
45-
}
46-
if (iface.id.name === 'CustomPagesOptions') {
47-
return 'PARSE_SERVER_CUSTOM_PAGES_';
48-
}
49-
if (iface.id.name === 'LiveQueryServerOptions') {
50-
return 'PARSE_LIVE_QUERY_SERVER_';
51-
}
52-
if (iface.id.name === 'LiveQueryOptions') {
53-
return 'PARSE_SERVER_LIVEQUERY_';
54-
}
55-
if (iface.id.name === 'IdempotencyOptions') {
56-
return 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_';
43+
let name = iface.id.name;
44+
if (name.indexOf('Options') === -1) {
45+
return;
5746
}
47+
name = name.replace('Options','').replace('ParseServer','');
48+
const splitName = name.split(/(?=[A-Z])/).map(name => name.toUpperCase());
49+
return `PARSE_SERVER_${splitName.join('_')}_`.replace('__','_');
5850
}
5951

6052
function processProperty(property, iface) {

src/Options/Definitions.js

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ module.exports.ParseServerOptions = {
127127
},
128128
emailVerifyTokenReuseIfValid: {
129129
env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_REUSE_IF_VALID',
130-
help: 'an existing password reset token should be reused when a password reset is requested',
130+
help: 'an existing password reset token should be reused when resend verification is requested',
131131
action: parsers.booleanParser,
132132
default: false,
133133
},
@@ -451,103 +451,151 @@ module.exports.LiveQueryOptions = {
451451
action: parsers.arrayParser,
452452
},
453453
pubSubAdapter: {
454-
env: 'PARSE_SERVER_LIVEQUERY_PUB_SUB_ADAPTER',
454+
env: 'PARSE_SERVER_LIVE_QUERY_PUB_SUB_ADAPTER',
455455
help: 'LiveQuery pubsub adapter',
456456
action: parsers.moduleOrObjectParser,
457457
},
458458
redisOptions: {
459-
env: 'PARSE_SERVER_LIVEQUERY_REDIS_OPTIONS',
459+
env: 'PARSE_SERVER_LIVE_QUERY_REDIS_OPTIONS',
460460
help: "parse-server's LiveQuery redisOptions",
461461
action: parsers.objectParser,
462462
},
463463
redisURL: {
464-
env: 'PARSE_SERVER_LIVEQUERY_REDIS_URL',
464+
env: 'PARSE_SERVER_LIVE_QUERY_REDIS_URL',
465465
help: "parse-server's LiveQuery redisURL",
466466
},
467467
wssAdapter: {
468-
env: 'PARSE_SERVER_LIVEQUERY_WSS_ADAPTER',
468+
env: 'PARSE_SERVER_LIVE_QUERY_WSS_ADAPTER',
469469
help: 'Adapter module for the WebSocketServer',
470470
action: parsers.moduleOrObjectParser,
471471
},
472472
};
473473
module.exports.LiveQueryServerOptions = {
474474
appId: {
475-
env: 'PARSE_LIVE_QUERY_SERVER_APP_ID',
475+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_APP_ID',
476476
help:
477477
'This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId.',
478478
},
479479
cacheTimeout: {
480-
env: 'PARSE_LIVE_QUERY_SERVER_CACHE_TIMEOUT',
480+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_CACHE_TIMEOUT',
481481
help:
482482
"Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds).",
483483
action: parsers.numberParser('cacheTimeout'),
484484
},
485485
keyPairs: {
486-
env: 'PARSE_LIVE_QUERY_SERVER_KEY_PAIRS',
486+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_KEY_PAIRS',
487487
help:
488488
'A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details.',
489489
action: parsers.objectParser,
490490
},
491491
logLevel: {
492-
env: 'PARSE_LIVE_QUERY_SERVER_LOG_LEVEL',
492+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_LOG_LEVEL',
493493
help:
494494
'This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO.',
495495
},
496496
masterKey: {
497-
env: 'PARSE_LIVE_QUERY_SERVER_MASTER_KEY',
497+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_MASTER_KEY',
498498
help:
499499
'This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey.',
500500
},
501501
port: {
502-
env: 'PARSE_LIVE_QUERY_SERVER_PORT',
502+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_PORT',
503503
help: 'The port to run the LiveQuery server, defaults to 1337.',
504504
action: parsers.numberParser('port'),
505505
default: 1337,
506506
},
507507
pubSubAdapter: {
508-
env: 'PARSE_LIVE_QUERY_SERVER_PUB_SUB_ADAPTER',
508+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_PUB_SUB_ADAPTER',
509509
help: 'LiveQuery pubsub adapter',
510510
action: parsers.moduleOrObjectParser,
511511
},
512512
redisOptions: {
513-
env: 'PARSE_LIVE_QUERY_SERVER_REDIS_OPTIONS',
513+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_REDIS_OPTIONS',
514514
help: "parse-server's LiveQuery redisOptions",
515515
action: parsers.objectParser,
516516
},
517517
redisURL: {
518-
env: 'PARSE_LIVE_QUERY_SERVER_REDIS_URL',
518+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_REDIS_URL',
519519
help: "parse-server's LiveQuery redisURL",
520520
},
521521
serverURL: {
522-
env: 'PARSE_LIVE_QUERY_SERVER_SERVER_URL',
522+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_SERVER_URL',
523523
help:
524524
'This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL.',
525525
},
526526
websocketTimeout: {
527-
env: 'PARSE_LIVE_QUERY_SERVER_WEBSOCKET_TIMEOUT',
527+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_WEBSOCKET_TIMEOUT',
528528
help:
529529
'Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s).',
530530
action: parsers.numberParser('websocketTimeout'),
531531
},
532532
wssAdapter: {
533-
env: 'PARSE_LIVE_QUERY_SERVER_WSS_ADAPTER',
533+
env: 'PARSE_SERVER_LIVE_QUERY_SERVER_WSS_ADAPTER',
534534
help: 'Adapter module for the WebSocketServer',
535535
action: parsers.moduleOrObjectParser,
536536
},
537537
};
538538
module.exports.IdempotencyOptions = {
539539
paths: {
540-
env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_PATHS',
540+
env: 'PARSE_SERVER_IDEMPOTENCY_PATHS',
541541
help:
542542
'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.',
543543
action: parsers.arrayParser,
544544
default: [],
545545
},
546546
ttl: {
547-
env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_TTL',
547+
env: 'PARSE_SERVER_IDEMPOTENCY_TTL',
548548
help:
549549
'The duration in seconds after which a request record is discarded from the database, defaults to 300s.',
550550
action: parsers.numberParser('ttl'),
551551
default: 300,
552552
},
553553
};
554+
module.exports.AccountLockoutOptions = {
555+
duration: {
556+
env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_DURATION',
557+
help:
558+
'number of minutes that a locked-out account remains locked out before automatically becoming unlocked.',
559+
action: parsers.numberParser('duration'),
560+
},
561+
threshold: {
562+
env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_THRESHOLD',
563+
help: 'number of failed sign-in attempts that will cause a user account to be locked',
564+
action: parsers.numberParser('threshold'),
565+
},
566+
};
567+
module.exports.PasswordPolicyOptions = {
568+
doNotAllowUsername: {
569+
env: 'PARSE_SERVER_PASSWORD_POLICY_DO_NOT_ALLOW_USERNAME',
570+
help: 'disallow username in passwords',
571+
action: parsers.booleanParser,
572+
},
573+
maxPasswordAge: {
574+
env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_AGE',
575+
help: 'days for password expiry',
576+
action: parsers.numberParser('maxPasswordAge'),
577+
},
578+
maxPasswordHistory: {
579+
env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_HISTORY',
580+
help: 'setting to prevent reuse of previous n passwords',
581+
action: parsers.numberParser('maxPasswordHistory'),
582+
},
583+
resetTokenReuseIfValid: {
584+
env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID',
585+
help: "resend token if it's still valid",
586+
action: parsers.booleanParser,
587+
},
588+
resetTokenValidityDuration: {
589+
env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_VALIDITY_DURATION',
590+
help: 'time for token to expire',
591+
action: parsers.numberParser('resetTokenValidityDuration'),
592+
},
593+
validatorCallback: {
594+
env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_CALLBACK',
595+
help: 'a callback function to be invoked to validate the password',
596+
},
597+
validatorPattern: {
598+
env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_PATTERN',
599+
help: 'a RegExp object or a regex string representing the pattern to enforce',
600+
},
601+
};

src/Options/docs.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @interface ParseServerOptions
3-
* @property {Any} accountLockout account lockout policy for failed login attempts
3+
* @property {AccountLockoutOptions} accountLockout account lockout policy for failed login attempts
44
* @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true
55
* @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId
66
* @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers
@@ -23,7 +23,7 @@
2323
* @property {Boolean} directAccess Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production.
2424
* @property {String} dotNetKey Key for Unity and .Net SDK
2525
* @property {Adapter<MailAdapter>} emailAdapter Adapter module for email sending
26-
* @property {Boolean} emailVerifyTokenReuseIfValid an existing password reset token should be reused when a password reset is requested
26+
* @property {Boolean} emailVerifyTokenReuseIfValid an existing password reset token should be reused when resend verification is requested
2727
* @property {Number} emailVerifyTokenValidityDuration Email verification token validity duration, in seconds
2828
* @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true
2929
* @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors
@@ -53,7 +53,7 @@
5353
* @property {String} mountPath Mount path for the server, defaults to /parse
5454
* @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production
5555
* @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10
56-
* @property {Any} passwordPolicy Password policy for enforcing password related rules
56+
* @property {PasswordPolicyOptions} passwordPolicy Password policy for enforcing password related rules
5757
* @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground
5858
* @property {Number} port The port to run the ParseServer, defaults to 1337.
5959
* @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names
@@ -120,3 +120,20 @@
120120
* @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.
121121
* @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s.
122122
*/
123+
124+
/**
125+
* @interface AccountLockoutOptions
126+
* @property {Number} duration number of minutes that a locked-out account remains locked out before automatically becoming unlocked.
127+
* @property {Number} threshold number of failed sign-in attempts that will cause a user account to be locked
128+
*/
129+
130+
/**
131+
* @interface PasswordPolicyOptions
132+
* @property {Boolean} doNotAllowUsername disallow username in passwords
133+
* @property {Number} maxPasswordAge days for password expiry
134+
* @property {Number} maxPasswordHistory setting to prevent reuse of previous n passwords
135+
* @property {Boolean} resetTokenReuseIfValid resend token if it's still valid
136+
* @property {Number} resetTokenValidityDuration time for token to expire
137+
* @property {Function} validatorCallback a callback function to be invoked to validate the password
138+
* @property {String} validatorPattern a RegExp object or a regex string representing the pattern to enforce
139+
*/

src/Options/index.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ export interface ParseServerOptions {
128128
:DEFAULT: false */
129129
emailVerifyTokenReuseIfValid: ?boolean;
130130
/* account lockout policy for failed login attempts */
131-
accountLockout: ?any;
131+
accountLockout: ?AccountLockoutOptions;
132132
/* Password policy for enforcing password related rules */
133-
passwordPolicy: ?any;
133+
passwordPolicy: ?PasswordPolicyOptions;
134134
/* Adapter module for the cache */
135135
cacheAdapter: ?Adapter<CacheAdapter>;
136136
/* Adapter module for email sending */
@@ -291,3 +291,27 @@ export interface IdempotencyOptions {
291291
:DEFAULT: 300 */
292292
ttl: ?number;
293293
}
294+
295+
export interface AccountLockoutOptions {
296+
/* number of minutes that a locked-out account remains locked out before automatically becoming unlocked. */
297+
duration: ?number;
298+
/* number of failed sign-in attempts that will cause a user account to be locked */
299+
threshold: ?number;
300+
}
301+
302+
export interface PasswordPolicyOptions {
303+
/* a RegExp object or a regex string representing the pattern to enforce */
304+
validatorPattern: ?string;
305+
/* a callback function to be invoked to validate the password */
306+
validatorCallback: ?() => void;
307+
/* disallow username in passwords */
308+
doNotAllowUsername: ?boolean;
309+
/* days for password expiry */
310+
maxPasswordAge: ?number;
311+
/* setting to prevent reuse of previous n passwords */
312+
maxPasswordHistory: ?number;
313+
/* time for token to expire */
314+
resetTokenValidityDuration: ?number;
315+
/* resend token if it's still valid */
316+
resetTokenReuseIfValid: ?boolean;
317+
}

0 commit comments

Comments
 (0)