summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Carstairs <jcarstairs@scottlogic.com>2024-01-22 16:27:58 +0000
committerJoe Carstairs <jcarstairs@scottlogic.com>2024-01-29 10:51:49 +0000
commiteac3fb00ef11c08a277dd8f9e2684b79f15193c2 (patch)
tree1560e57bb5872d698565dc502aa7659d89c830a4
parentaf44cac699b0591eba908db3835c4e5792303095 (diff)
Authenticator db functions use Uint8Array type for id, public_key fields
-rw-r--r--api/db/_getAuthenticator.ts25
-rw-r--r--api/db/_getAuthenticators.ts20
-rw-r--r--api/db/_updateAuthenticator.ts6
3 files changed, 37 insertions, 14 deletions
diff --git a/api/db/_getAuthenticator.ts b/api/db/_getAuthenticator.ts
index e93023b..70c577c 100644
--- a/api/db/_getAuthenticator.ts
+++ b/api/db/_getAuthenticator.ts
@@ -1,14 +1,15 @@
+import type Authenticator from '../types/Authenticator';
+
import { sql } from '@vercel/postgres';
import { AUTHENTICATORS } from './_tables';
-import Authenticator from '../types/Authenticator';
export default async function getAuthenticator<
T extends keyof Authenticator
->(id: string, fields: T[]): Promise<Pick<Authenticator, T>> {
+>(id: Authenticator['id'], fields: T[]): Promise<Pick<Authenticator, T>> {
const query = `
SELECT ${fields.join(', ')}
FROM ${AUTHENTICATORS.name}
- WHERE ${AUTHENTICATORS.fields.id} = '${id}';
+ WHERE ${AUTHENTICATORS.fields.id} = '{ ${id.toString()} }';
`;
try {
@@ -16,16 +17,26 @@ export default async function getAuthenticator<
const row = result.rows.at(0);
if (!row) {
- throw new Error(`No authenticator with ID ${id} found in database.`);
+ throw new Error(`No authenticator with ID [${id.toString()}] found in database.`);
}
const authenticator: Partial<Pick<Authenticator, T>> = {};
for (const field in fields) {
- // Assume type conversion is already done by node-postgres
- authenticator[field] = row[AUTHENTICATORS.fields[field]];
+ switch (field) {
+ case 'id':
+ case 'public_key':
+ // Convert from number[] to Uint8Array
+ // We know that we'll get Postgres integer[] as JavaScript number[]:
+ // https://github.com/brianc/node-pg-types/blob/master/lib/textParsers.js
+ authenticator[field] = new Uint8Array(row[AUTHENTICATORS.fields[field]]);
+ break;
+ default:
+ // Assume adequate type conversion is already done by node-postgres
+ authenticator[field] = row[AUTHENTICATORS.fields[field]];
+ }
}
return authenticator as Pick<Authenticator, T>;
} catch (err) {
- throw new Error(`Failed to get authenticator with ID ${id} from database. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
+ throw new Error(`Failed to get authenticator with ID [${id.toString()}] from database. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
}
}
diff --git a/api/db/_getAuthenticators.ts b/api/db/_getAuthenticators.ts
index 1286b90..51f1254 100644
--- a/api/db/_getAuthenticators.ts
+++ b/api/db/_getAuthenticators.ts
@@ -1,10 +1,12 @@
+import type Authenticator from '../types/Authenticator';
+import type User from '../types/User';
+
import { sql } from '@vercel/postgres';
import { AUTHENTICATORS } from './_tables';
-import Authenticator from '../types/Authenticator';
export default async function getAuthenticators<
T extends keyof Authenticator
->(userId: string, fields: T[]): Promise<Pick<Authenticator, T>[]> {
+>(userId: User['id'], fields: T[]): Promise<Pick<Authenticator, T>[]> {
const query = `
SELECT ${fields.join(', ')}
FROM ${AUTHENTICATORS.name}
@@ -17,8 +19,18 @@ export default async function getAuthenticators<
return result.rows.map((row) => {
const authenticator: Partial<Pick<Authenticator, T>> = {};
for (const field in fields) {
- // Assume type conversion is already done by node-postgres
- authenticator[field] = row[AUTHENTICATORS.fields[field]];
+ switch (field) {
+ case 'id':
+ case 'public_key':
+ // Convert from number[] to Uint8Array
+ // We know that we'll get Postgres integer[] as JavaScript number[]:
+ // https://github.com/brianc/node-pg-types/blob/master/lib/textParsers.js
+ authenticator[field] = new Uint8Array(row[AUTHENTICATORS.fields[field]]);
+ break;
+ default:
+ // Assume adequate type conversion is already done by node-postgres
+ authenticator[field] = row[AUTHENTICATORS.fields[field]];
+ }
}
return authenticator as Pick<Authenticator, T>;
});
diff --git a/api/db/_updateAuthenticator.ts b/api/db/_updateAuthenticator.ts
index a7e06e3..6c72327 100644
--- a/api/db/_updateAuthenticator.ts
+++ b/api/db/_updateAuthenticator.ts
@@ -5,7 +5,7 @@ import { AUTHENTICATORS } from './_tables';
export default async function updateAuthenticator<
T extends keyof Omit<Authenticator, 'id'>
->(id: string, updatedFields: Pick<Authenticator, T>): Promise<void> {
+>(id: Authenticator['id'], updatedFields: Pick<Authenticator, T>): Promise<void> {
const assignments = Object.entries(updatedFields)
.filter(([key]) => key !== 'id') // never update the ID
.map(([key, value]) => `${key}=${value}`)
@@ -14,12 +14,12 @@ export default async function updateAuthenticator<
const query = `
UPDATE ${AUTHENTICATORS.name}
SET ${assignments}
- WHERE ${AUTHENTICATORS.fields.id} = '${id}';
+ WHERE ${AUTHENTICATORS.fields.id} = '{ ${id.toString()} }';
`;
try {
await sql.query(query);
} catch (err) {
- throw new Error(`Failed to update authenticator with ID ${id} in database. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
+ throw new Error(`Failed to update authenticator with ID [${id.toString()}] in database. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
}
}