}
+ /**
+ * @typedef {Object} SchemaVersionObject
+ * @property {Number} major
+ * @property {Number} minor
+ * @property {Number} patch
+ */
/**
* Query the current schema version.
* This is a standalone query function, as it is called before statements are loaded.
- * @returns {Object} version
- * @returns {Number} version.major
- * @returns {Number} version.minor
- * @returns {Number} version.patch
+ * @returns {Promise<SchemaVersionObject>}
*/
async _currentSchema() {
this._notImplemented('_currentSchema', arguments);
}
- /**
- * @param {*} x
- * @returns {Boolean}
- */
- static _isUUID(x) {
- try {
- uuid.parse(x);
- return true;
- } catch (e) {
- return false;
- }
- }
-
-
- /**
- * @param {*} x
- * @returns {Boolean}
- */
- static _isInfinites(x) {
- return typeof(x) === 'number'
- && Math.abs(x) === Infinity;
- }
-
/**
* Basic type checking of object properties.
+ *
+ * Types may be any of the built-in types:
+ * - boolean
+ * - bigint (also allowed with 'number')
+ * - function
+ * - number (this will also allow 'bigint')
+ * - object
+ * - string
+ * - symbol
+ * - undefined
+ *
+ * Types may also be any of the following:
+ * - array
+ * - buffer
+ * - date
+ * - infinites
+ * - null
+ * - uuid
* @param {Object} object
* @param {String[]} properties
* @param {String[]} types
this.logger.error(_scope, 'undefined argument', { object, properties, types });
throw new DatabaseErrors.DataValidation();
}
+
+ const supportedTypes = [
+ 'array',
+ 'bigint',
+ 'boolean',
+ 'buffer',
+ 'date',
+ 'function',
+ 'infinites',
+ 'null',
+ 'number',
+ 'object',
+ 'string',
+ 'symbol',
+ 'undefined',
+ 'uuid',
+ ];
+ types.forEach((t) => {
+ if (!supportedTypes.includes(t)) {
+ this.logger.error(_scope, 'unsupported type', { object, properties, types, unsupportedType: t });
+ throw new DatabaseErrors.DataValidation();
+ }
+ });
+
properties.forEach((p) => {
// eslint-disable-next-line security/detect-object-injection
const pObj = object[p];
&& !(types.includes('array') && Array.isArray(pObj))
&& !(types.includes('buffer') && pObj instanceof Buffer)
&& !(types.includes('date') && pObj instanceof Date)
- && !(types.includes('infinites'))
+ && !(types.includes('infinites') && Math.abs(pObj) === Infinity)
&& !(types.includes('null') && pObj === null)
&& !(types.includes('number') && pType === 'bigint')
- && !(types.includes('uuid') && Database._isUUID(pObj))) {
+ && !(types.includes('uuid') && uuid.validate(pObj))) {
const reason = `'${p}' is '${pType}', but must be ${types.length > 1 ? 'one of ' : ''}'${types}'`;
this.logger.error(_scope, reason, {});
throw new DatabaseErrors.DataValidation(reason);
* @property {String} identifier
* @property {String=} credential
* @property {Date} created
- * @property {Date=} lastAuthenticated
+ * @property {Date=} lastAuthentication
*/
/**
* @param {Authentication} authentication
[['identifier'], ['string']],
[['credential'], ['string', 'null']],
[['created'], ['date']],
- [['lastAuthenticated'], ['date', 'infinites']],
+ [['lastAuthentication'], ['date', 'infinites']],
].forEach(([properties, types]) => this._ensureTypes(authentication, properties, types));
}
}
+ /**
+ * Insert or update an almanac entry.
+ * @param {*} dbCtx
+ * @param {String} event
+ * @param {Date=} date
+ */
+ async almanacUpsert(dbCtx, event, date) {
+ this._notImplemented('almanacUpsert', arguments);
+ }
+
+
/**
* Fetch the authentication record for an identifier.
* @param {*} dbCtx
* @param {*} dbCtx
* @param {String} identifier
* @param {String} credential
+ * @param {String=} otpKey
* @returns {Promise<void>}
*/
- async authenticationUpsert(dbCtx, identifier, credential) {
+ async authenticationUpsert(dbCtx, identifier, credential, otpKey) {
this._notImplemented('authenticationUpsert', arguments);
}
+ /**
+ * Update the otpKey for an identifier.
+ * @param {*} dbCtx
+ * @param {String} identifier
+ * @param {String=} otpKey
+ * @returns {Promise<void>}
+ */
+ async authenticationUpdateOTPKey(dbCtx, identifier, otpKey) {
+ this._notImplemented('authenticationUpdateOTPKey', arguments);
+ }
+
+
+ /**
+ * Update the credential for an identifier.
+ * @param {*} dbCtx
+ * @param {String} identifier
+ * @param {String} credential
+ * @returns {Promise<void>}
+ */
+ async authenticationUpdateCredential(dbCtx, identifier, credential) {
+ this._notImplemented('authenticationUpdateCredentials', arguments);
+ }
+
+
/**
* Determine if profile url is known to this service.
* @param {*} dbCtx
this._notImplemented('tokensGetByIdentifier', arguments);
}
+
+ /** @typedef {Object} RedeemedTicketData
+ * @property {String} subject
+ * @property {String} resource
+ * @property {String=} iss
+ * @property {String} ticket
+ * @property {String} token
+ */
+ /**
+ * Persist details of a redeemed ticket.
+ * @param {*} dbCtx
+ * @param {RedeemedTicketData} redeemedData
+ * @returns {Promise<void>}
+ */
+ async ticketRedeemed(dbCtx, redeemedData) {
+ this._notImplemented('ticketRedeemed', arguments);
+ }
+
+
+ /**
+ * Update details of a redeemed ticket that it has been published.
+ * @param {*} dbCtx
+ * @param {RedeemedTicketData} redeemedData
+ * @returns {Promise<void>}
+ */
+ async ticketTokenPublished(dbCtx, redeemedData) {
+ this._notImplemented('ticketTokenPublished', arguments);
+ }
+
+ /**
+ * Retrieve redeemed tokens which have not yet been published to queue.
+ * @param {Number} limit
+ * @returns {Promise<RedeemedData[]>}
+ */
+ async ticketTokenGetUnpublished(dbCtx, limit) {
+ this._notImplemented('ticketTokenGetUnpublished', arguments);
+ }
+
}
-module.exports = Database;
\ No newline at end of file
+module.exports = Database;