diff options
| author | Joe Carstairs <jcarstairs@scottlogic.com> | 2024-01-22 16:27:58 +0000 |
|---|---|---|
| committer | Joe Carstairs <jcarstairs@scottlogic.com> | 2024-01-29 10:51:49 +0000 |
| commit | eac3fb00ef11c08a277dd8f9e2684b79f15193c2 (patch) | |
| tree | 1560e57bb5872d698565dc502aa7659d89c830a4 | |
| parent | af44cac699b0591eba908db3835c4e5792303095 (diff) | |
Authenticator db functions use Uint8Array type for id, public_key fields
| -rw-r--r-- | api/db/_getAuthenticator.ts | 25 | ||||
| -rw-r--r-- | api/db/_getAuthenticators.ts | 20 | ||||
| -rw-r--r-- | api/db/_updateAuthenticator.ts | 6 |
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}`); } } |
