X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=src%2Fdb%2Fpostgres%2Findex.js;h=8995ab189cfe7a6cc9888dd1d9c8388aedc943d1;hb=fba42a499fe1af051b0982c1f3e8b3873c9ed2fb;hp=3a536f48f5d4250cce11f0483843bbac74335b02;hpb=e7436419933940f90769c8be1d63acccdd947b92;p=squeep-indie-auther diff --git a/src/db/postgres/index.js b/src/db/postgres/index.js index 3a536f4..8995ab1 100644 --- a/src/db/postgres/index.js +++ b/src/db/postgres/index.js @@ -11,6 +11,7 @@ const { unappliedSchemaVersions } = require('../schema-version-helper'); const Database = require('../abstract'); const DBErrors = require('../errors'); const common = require('../../common'); +const Enum = require('../../enum'); const _fileScope = common.fileScope(__filename); @@ -28,7 +29,7 @@ const schemaVersionsSupported = { }, max: { major: 1, - minor: 0, + minor: 2, patch: 0, }, }; @@ -197,9 +198,11 @@ class DatabasePostgres extends Database { if (really) { await this.db.tx(async (t) => { await t.batch([ + 'almanac', 'authentication', - 'resource', 'profile', + 'redeemed_ticket', + 'resource', 'token', ].map(async (table) => t.query('TRUNCATE TABLE $(table:name) CASCADE', { table }))); }); @@ -222,6 +225,11 @@ class DatabasePostgres extends Database { } + static _almanacErrorThrow() { + throw new DBErrors.UnexpectedResult('did not update almanac'); + } + + async almanacGetAll(dbCtx) { const _scope = _fileScope('almanacGetAll'); this.logger.debug(_scope, 'called'); @@ -235,6 +243,22 @@ class DatabasePostgres extends Database { } + async almanacUpsert(dbCtx, event, date) { + const _scope = _fileScope('almanacUpsert'); + this.logger.debug(_scope, 'called', { event, date }); + + try { + const result = await dbCtx.result(this.statement.almanacUpsert, { event, date: date ?? new Date() }); + if (result.rowCount != 1) { + this.constructor._almanacErrorThrow(); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, event, date }); + throw e; + } + } + + async authenticationGet(dbCtx, identifier) { const _scope = _fileScope('authenticationGet'); this.logger.debug(_scope, 'called', { identifier }); @@ -264,20 +288,56 @@ class DatabasePostgres extends Database { } - async authenticationUpsert(dbCtx, identifier, credential) { + async authenticationUpsert(dbCtx, identifier, credential, otpKey) { const _scope = _fileScope('authenticationUpsert'); const scrubbedCredential = '*'.repeat((credential || '').length); - this.logger.debug(_scope, 'called', { identifier, scrubbedCredential }); + const scrubbedOTPKey = '*'.repeat((otpKey || '').length); + this.logger.debug(_scope, 'called', { identifier, scrubbedCredential, scrubbedOTPKey }); try { - const result = await dbCtx.result(this.statement.authenticationUpsert, { identifier, credential }); + const result = await dbCtx.result(this.statement.authenticationUpsert, { identifier, credential, otpKey }); if (result.rowCount != 1) { throw new DBErrors.UnexpectedResult('did not upsert authentication'); } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier, scrubbedCredential, scrubbedOTPKey }); + throw e; + } + } + + + async authenticationUpdateOTPKey(dbCtx, identifier, otpKey = null) { + const _scope = _fileScope('authenticationUpdateOTPKey'); + const scrubbedOTPKey = '*'.repeat((otpKey || '').length); + this.logger.debug(_scope, 'called', { identifier, scrubbedOTPKey }); + + try { + const result = await dbCtx.result(this.statement.authenticationUpdateOtpKey, { identifier, otpKey }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not update otpKey'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier, scrubbedOTPKey }); + throw e; + } + } + + + async authenticationUpdateCredential(dbCtx, identifier, credential) { + const _scope = _fileScope('authenticationUpdateCredential'); + const scrubbedCredential = '*'.repeat((credential || '').length); + this.logger.debug(_scope, 'called', { identifier, scrubbedCredential }); + + try { + const result = await dbCtx.result(this.statement.authenticationUpdateCredential, { identifier, credential }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not update credential'); + } } catch (e) { this.logger.error(_scope, 'failed', { error: e, identifier, scrubbedCredential }); throw e; } + } @@ -464,7 +524,7 @@ class DatabasePostgres extends Database { const _scope = _fileScope('scopeCleanup'); this.logger.debug(_scope, 'called', { atLeastMsSinceLast }); - const almanacEvent = 'scopeCleanup'; + const almanacEvent = Enum.AlmanacEntry.ScopeCleanup; try { return await this.transaction(dbCtx, async (txCtx) => { @@ -483,7 +543,7 @@ class DatabasePostgres extends Database { // Update the last cleanup time const result = await txCtx.result(this.statement.almanacUpsert, { event: almanacEvent, date: now }); if (result.rowCount != 1) { - throw new DBErrors.UnexpectedResult('did not update almanac'); + this.constructor._almanacErrorThrow(); } this.logger.debug(_scope, 'completed', { scopesRemoved, atLeastMsSinceLast }); @@ -543,7 +603,7 @@ class DatabasePostgres extends Database { const _scope = _fileScope('tokenCleanup'); this.logger.debug(_scope, 'called', { codeLifespanSeconds, atLeastMsSinceLast }); - const almanacEvent = 'tokenCleanup'; + const almanacEvent = Enum.AlmanacEntry.TokenCleanup; try { return await this.transaction(dbCtx, async (txCtx) => { @@ -562,7 +622,7 @@ class DatabasePostgres extends Database { // Update the last cleanup time const result = await txCtx.result(this.statement.almanacUpsert, { event: almanacEvent, date: now }); if (result.rowCount != 1) { - throw new DBErrors.UnexpectedResult('did not update almanac'); + this.constructor._almanacErrorThrow(); } this.logger.debug(_scope, 'completed', { tokensRemoved, codeLifespanSeconds, atLeastMsSinceLast }); @@ -633,6 +693,55 @@ class DatabasePostgres extends Database { } } + + async ticketRedeemed(dbCtx, redeemedData) { + const _scope = _fileScope('ticketRedeemed'); + this.logger.debug(_scope, 'called', { ...redeemedData }); + + try { + const result = await dbCtx.result(this.statement.ticketRedeemed, redeemedData); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not store redeemed ticket'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, ...redeemedData }); + throw e; + } + } + + + async ticketTokenPublished(dbCtx, redeemedData) { + const _scope = _fileScope('ticketRedeemed'); + this.logger.debug(_scope, 'called', { ...redeemedData }); + + const almanacEvent = Enum.AlmanacEntry.TicketPublished; + try { + const result = await dbCtx.result(this.statement.ticketTokenPublished, redeemedData); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not store redeemed ticket'); + } + const almanacResult = await dbCtx.result(this.statement.almanacUpsert, { event: almanacEvent, date: new Date() }); + if (almanacResult.rowCount != 1) { + this.constructor._almanacErrorThrow(); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, ...redeemedData }); + throw e; + } + } + + async ticketTokenGetUnpublished(dbCtx) { + const _scope = _fileScope('ticketTokenGetUnpublished'); + this.logger.debug(_scope, 'called'); + + try { + return await dbCtx.manyOrNone(this.statement.ticketTokenGetUnpublished); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + } module.exports = DatabasePostgres;