diff --git a/keyserver/src/user/identity.js b/keyserver/src/user/identity.js --- a/keyserver/src/user/identity.js +++ b/keyserver/src/user/identity.js @@ -9,33 +9,51 @@ import type { UserCredentials } from './checks'; import { SQL, dbQuery } from '../database/database.js'; -const userIDMetadataKey = 'user_id'; -const accessTokenMetadataKey = 'access_token'; +const MetadataKeys = Object.freeze({ + USER_ID: 'user_id', + ACCESS_TOKEN: 'access_token', +}); + +type MetadataKey = $Values; // This information is minted when registering with identity service // Naming should reflect the rust-bindings: userId -> user_id export type IdentityInfo = { +userId: string, +accessToken: string }; -async function fetchIdentityInfo(): Promise { - const versionQuery = SQL` +// This function should only be used to fetch string values from the metadata +// table +async function fetchMetadata( + keys: $ReadOnlyArray, +): Promise> { + const metadataQuery = SQL` SELECT name, data FROM metadata - WHERE name IN (${userIDMetadataKey}, ${accessTokenMetadataKey}) + WHERE name IN (${keys}) `; - const [result] = await dbQuery(versionQuery); - let userID, accessToken; + const [result] = await dbQuery(metadataQuery); + + const metadataMap = new Map(); + for (const row of result) { - if (row.name === userIDMetadataKey) { - userID = row.data; - } else if (row.name === accessTokenMetadataKey) { - accessToken = row.data; - } + metadataMap.set(row.name, row.data); } + return metadataMap; +} + +async function fetchIdentityInfo(): Promise { + const keys = [MetadataKeys.USER_ID, MetadataKeys.ACCESS_TOKEN]; + + const metadataMap = await fetchMetadata(keys); + + const userID = metadataMap.get(MetadataKeys.USER_ID); + const accessToken = metadataMap.get(MetadataKeys.ACCESS_TOKEN); + if (!userID || !accessToken) { return null; } + return { userId: userID, accessToken }; } @@ -82,16 +100,24 @@ }; } -function saveIdentityInfo(userInfo: IdentityInfo): Promise { - const updateQuery = SQL` - REPLACE INTO metadata (name, data) - VALUES (${userIDMetadataKey}, ${userInfo.userId}), - (${accessTokenMetadataKey}, ${userInfo.accessToken}) - `; +function saveMetadata( + metadataMap: Map, +): Promise { + const updateQuery = SQL`REPLACE INTO metadata (name, data)`; + const entries = [...metadataMap.entries()]; + updateQuery.append(SQL` VALUES ${entries}`); return dbQuery(updateQuery); } +function saveIdentityInfo(userInfo: IdentityInfo): Promise { + const metadataMap = new Map(); + metadataMap.set(MetadataKeys.USER_ID, userInfo.userId); + metadataMap.set(MetadataKeys.ACCESS_TOKEN, userInfo.accessToken); + + return saveMetadata(metadataMap); +} + export { fetchIdentityInfo, thisKeyserverID,