From 0f2a55d2748eab20f560f8d7aae1636ab31f1635 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 27 May 2022 13:01:20 +0800 Subject: [PATCH] Add list/delete api key resolver --- packages/api/src/resolvers/api_key/index.ts | 83 +++++++++++++++++++ .../api/src/resolvers/function_resolvers.ts | 9 +- packages/api/src/resolvers/index.ts | 1 + 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/packages/api/src/resolvers/api_key/index.ts b/packages/api/src/resolvers/api_key/index.ts index b6f55f92e..8cd6f601f 100644 --- a/packages/api/src/resolvers/api_key/index.ts +++ b/packages/api/src/resolvers/api_key/index.ts @@ -1,7 +1,14 @@ import { + ApiKeysError, + ApiKeysErrorCode, + ApiKeysSuccess, + DeleteApiKeyError, + DeleteApiKeyErrorCode, + DeleteApiKeySuccess, GenerateApiKeyError, GenerateApiKeyErrorCode, GenerateApiKeySuccess, + MutationDeleteApiKeyArgs, MutationGenerateApiKeyArgs, } from '../../generated/graphql' import { analytics } from '../../utils/analytics' @@ -12,6 +19,36 @@ import { User } from '../../entity/user' import { ApiKey } from '../../entity/api_key' import { generateApiKey, hashApiKey } from '../../utils/auth' +export const apiKeysResolver = authorized( + async (_, __, { claims: { uid }, log }) => { + log.info('apiKeysResolver') + + try { + const user = await getRepository(User).findOneBy({ id: uid }) + if (!user) { + return { + errorCodes: [ApiKeysErrorCode.Unauthorized], + } + } + + const apiKeys = await getRepository(ApiKey).find({ + where: { user: { id: uid } }, + order: { usedAt: 'DESC', createdAt: 'DESC' }, + }) + + return { + apiKeys, + } + } catch (e) { + log.error(e) + + return { + errorCodes: [ApiKeysErrorCode.BadRequest], + } + } + } +) + export const generateApiKeyResolver = authorized< GenerateApiKeySuccess, GenerateApiKeyError, @@ -62,3 +99,49 @@ export const generateApiKeyResolver = authorized< return { errorCodes: [GenerateApiKeyErrorCode.BadRequest] } } }) + +export const deleteApiKeyResolver = authorized< + DeleteApiKeySuccess, + DeleteApiKeyError, + MutationDeleteApiKeyArgs +>(async (_, { id }, { claims: { uid }, log }) => { + log.info('deleteApiKeyResolver') + + try { + const user = await getRepository(User).findOneBy({ id: uid }) + if (!user) { + return { + errorCodes: [DeleteApiKeyErrorCode.Unauthorized], + } + } + + const apiKey = await getRepository(ApiKey).findOne({ + where: { id }, + relations: ['user'], + }) + if (!apiKey) { + return { + errorCodes: [DeleteApiKeyErrorCode.NotFound], + } + } + + if (apiKey.user.id !== uid) { + return { + errorCodes: [DeleteApiKeyErrorCode.Unauthorized], + } + } + + const deletedApiKey = await getRepository(ApiKey).remove(apiKey) + deletedApiKey.id = id + + return { + apiKey: deletedApiKey, + } + } catch (e) { + log.error(e) + + return { + errorCodes: [DeleteApiKeyErrorCode.BadRequest], + } + } +}) diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index de13e589d..4a3c828a8 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -21,6 +21,8 @@ import { } from './../generated/graphql' import { + addPopularReadResolver, + apiKeysResolver, articleSavingRequestResolver, createArticleResolver, createArticleSavingRequestResolver, @@ -28,11 +30,13 @@ import { createLabelResolver, createNewsletterEmailResolver, createReminderResolver, + deleteApiKeyResolver, deleteHighlightResolver, deleteLabelResolver, deleteNewsletterEmailResolver, deleteReminderResolver, deleteWebhookResolver, + generateApiKeyResolver, getAllUsersResolver, getArticleResolver, getArticlesResolver, @@ -90,7 +94,6 @@ import { generateUploadFilePathName, } from '../utils/uploads' import { getPageByParam } from '../elastic/pages' -import { generateApiKeyResolver } from './api_key' /* eslint-disable @typescript-eslint/naming-convention */ type ResultResolveType = { @@ -157,6 +160,7 @@ export const functionResolvers = { addPopularRead: addPopularReadResolver, setWebhook: setWebhookResolver, deleteWebhook: deleteWebhookResolver, + deleteApiKey: deleteApiKeyResolver, }, Query: { me: getMeUserResolver, @@ -178,6 +182,7 @@ export const functionResolvers = { subscriptions: subscriptionsResolver, webhooks: webhooksResolver, webhook: webhookResolver, + apiKeys: apiKeysResolver, }, User: { async sharedArticles( @@ -575,4 +580,6 @@ export const functionResolvers = { ...resultResolveTypeResolver('Webhooks'), ...resultResolveTypeResolver('DeleteWebhook'), ...resultResolveTypeResolver('Webhook'), + ...resultResolveTypeResolver('ApiKeys'), + ...resultResolveTypeResolver('DeleteApiKey'), } diff --git a/packages/api/src/resolvers/index.ts b/packages/api/src/resolvers/index.ts index 58434a7e4..e510db671 100644 --- a/packages/api/src/resolvers/index.ts +++ b/packages/api/src/resolvers/index.ts @@ -18,3 +18,4 @@ export * from './subscriptions' export * from './update' export * from './popular_reads' export * from './webhooks' +export * from './api_key'