Skip to content

Commit 1a8ed13

Browse files
committed
rename apiKey to ApiAccess
1 parent 1c72b19 commit 1a8ed13

File tree

11 files changed

+110
-114
lines changed

11 files changed

+110
-114
lines changed

services/src/auth/api-key-repository.integration.test.ts renamed to services/src/auth/api-access-repository.integration.test.ts

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { beforeEach, describe, expect, it } from 'vitest'
22
import { db } from '../db/database'
33
import { runMigration } from '../db/database-migration-util'
44
import { createProject } from '../project/project.repository'
5-
import type { ProjectId } from '../../../src/routes/(api)/api/api.model'
65
import {
7-
createApiKey,
8-
deleteApiKey,
9-
getApiKeysForProject,
6+
createApiAccess,
7+
deleteApiAccess,
8+
getApiAccessForProject,
109
projectHasKey,
11-
setApiKeyName
12-
} from './api-key.repository'
10+
setApiAccessName
11+
} from './api-access.repository'
12+
import type { ProjectId } from '../project/project'
1313

1414
beforeEach(async () => {
1515
db.reset()
@@ -22,94 +22,94 @@ describe('ApiKey Repository', () => {
2222
projectId = (await createProject({ name: 'demo project name' })).id as ProjectId
2323
})
2424

25-
describe('createApiKey', () => {
25+
describe('createApiAccess', () => {
2626
it('should create an api key given an existing project', async () => {
27-
const result = await createApiKey(projectId)
27+
const result = await createApiAccess(projectId)
2828
expect(result).toBeTruthy()
2929
expect(false).toBeFalsy()
3030
})
3131
})
3232

33-
describe('getApiKeysForProject', () => {
33+
describe('getApiAccessForProject', () => {
3434
it('should fetch all apiKeys for a given project', async () => {
35-
const key1 = await createApiKey(projectId)
36-
const key2 = await createApiKey(projectId)
35+
const access1 = await createApiAccess(projectId)
36+
const access2 = await createApiAccess(projectId)
3737

38-
const result = (await getApiKeysForProject(projectId)).map((it) => it.key)
39-
expect(result).toHaveLength(2)
40-
expect(result).includes(key1.key)
41-
expect(result).includes(key2.key)
38+
const keys = (await getApiAccessForProject(projectId)).map((it) => it.apikey)
39+
expect(keys).toHaveLength(2)
40+
expect(keys).includes(access1.apikey)
41+
expect(keys).includes(access2.apikey)
4242
})
4343

4444
it('should retrieve the name of the apiKey when it is created with one', async () => {
4545
const name = 'some key name'
46-
const key = await createApiKey(projectId, name)
47-
const result = await getApiKeysForProject(projectId)
46+
const key = await createApiAccess(projectId, name)
47+
const result = await getApiAccessForProject(projectId)
4848

49-
expect(result.find((it) => it.key === key.key)?.name).toBe(name)
49+
expect(result.find((it) => it.apikey === key.apikey)?.name).toBe(name)
5050
})
5151

5252
it('should no longer find deleted keys', async () => {
53-
const key = await createApiKey(projectId)
53+
const key = await createApiAccess(projectId)
5454

55-
const keysBeforeDelete = await getApiKeysForProject(projectId)
56-
expect(keysBeforeDelete.map((it) => it.key)).toContain(key.key)
55+
const keysBeforeDelete = await getApiAccessForProject(projectId)
56+
expect(keysBeforeDelete.map((it) => it.apikey)).toContain(key.apikey)
5757

58-
await deleteApiKey(projectId, key.key)
59-
const keysAfterDelete = await getApiKeysForProject(projectId)
60-
expect(keysAfterDelete.map((it) => it.key).includes(key.key)).toBe(false)
58+
await deleteApiAccess(projectId, key.apikey)
59+
const keysAfterDelete = await getApiAccessForProject(projectId)
60+
expect(keysAfterDelete.map((it) => it.apikey).includes(key.apikey)).toBe(false)
6161
})
6262

6363
it('should return an empty list in case the project does not exist', async () => {
64-
const keys = await getApiKeysForProject(projectId)
64+
const keys = await getApiAccessForProject(projectId)
6565
expect(keys).toHaveLength(0)
6666
})
6767

6868
it('should return an empty list if there are no keys', async () => {
69-
const result = await getApiKeysForProject(projectId)
69+
const result = await getApiAccessForProject(projectId)
7070
expect(result).toHaveLength(0)
7171
})
7272
})
7373

74-
describe('setApiKeyName', () => {
74+
describe('setApiAccessName', () => {
7575
it('should be able to set a name when previously there was none', async () => {
76-
const key = await createApiKey(projectId)
77-
const initialRetrieval = await getApiKeysForProject(projectId).then((it) =>
78-
it.find((apiKey) => apiKey.key === key.key)
76+
const key = await createApiAccess(projectId)
77+
const initialRetrieval = await getApiAccessForProject(projectId).then((it) =>
78+
it.find((apiKey) => apiKey.apikey === key.apikey)
7979
)
8080

8181
expect(initialRetrieval?.name).toBeFalsy()
8282
const updatedName = 'some new apiKeyName'
83-
await setApiKeyName(key.id, updatedName)
83+
await setApiAccessName(key.id, updatedName)
8484

85-
const secondRetrieval = await getApiKeysForProject(projectId).then((it) =>
86-
it.find((apiKey) => apiKey.key === key.key)
85+
const secondRetrieval = await getApiAccessForProject(projectId).then((it) =>
86+
it.find((apiKey) => apiKey.apikey === key.apikey)
8787
)
8888
expect(secondRetrieval?.name).toBe(updatedName)
8989
})
9090

9191
it('should be able to set the name', async () => {
9292
const initialName = 'my personal api key'
93-
const key = await createApiKey(projectId, initialName)
94-
const initialRetrieval = await getApiKeysForProject(projectId).then((it) =>
95-
it.find((apiKey) => apiKey.key === key.key)
93+
const key = await createApiAccess(projectId, initialName)
94+
const initialRetrieval = await getApiAccessForProject(projectId).then((it) =>
95+
it.find((apiKey) => apiKey.apikey === key.apikey)
9696
)
9797

9898
expect(initialRetrieval?.name).toBe(initialName)
9999
const updatedName = 'some new apiKeyName'
100-
await setApiKeyName(key.id, updatedName)
100+
await setApiAccessName(key.id, updatedName)
101101

102-
const secondRetrieval = await getApiKeysForProject(projectId).then((it) =>
103-
it.find((apiKey) => apiKey.key === key.key)
102+
const secondRetrieval = await getApiAccessForProject(projectId).then((it) =>
103+
it.find((apiKey) => apiKey.apikey === key.apikey)
104104
)
105105
expect(secondRetrieval?.name).toBe(updatedName)
106106
})
107107
})
108108

109109
describe('projectHasKey', () => {
110110
it('should return true if there is a key for the project', async () => {
111-
const key = await createApiKey(projectId)
112-
const result = await projectHasKey(projectId, key.key)
111+
const key = await createApiAccess(projectId)
112+
const result = await projectHasKey(projectId, key.apikey)
113113
expect(result).toBe(true)
114114
})
115115

@@ -125,9 +125,9 @@ describe('ApiKey Repository', () => {
125125

126126
it('should return false if key and project exist, but do not match', async () => {
127127
const otherProjectId = (await createProject({ name: 'another Project' })).id as ProjectId
128-
const key = await createApiKey(projectId)
128+
const key = await createApiAccess(projectId)
129129

130-
const result = await projectHasKey(otherProjectId, key.key)
130+
const result = await projectHasKey(otherProjectId, key.apikey)
131131
expect(result).toBe(false)
132132
})
133133
})
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
11
import { db } from '../db/database'
2-
import type { ApiKeyCreationParams, SelectableApiKey } from './api-key'
2+
import type { ApiKeyCreationParams, SelectableApiKey } from './api-access'
33
import { v4 as uuid } from 'uuid'
44

5-
export function createApiKey(
5+
export function createApiAccess(
66
projectId: number,
77
name: string | null = null
88
): Promise<SelectableApiKey> {
99
const insertKey: ApiKeyCreationParams = {
10-
key: uuid(),
10+
apikey: uuid(),
1111
name,
1212
project_id: projectId
1313
}
1414
return db
15-
.insertInto('apikeys')
15+
.insertInto('apiaccess')
1616
.values(insertKey)
1717
.returningAll()
1818
.executeTakeFirstOrThrow(() => new Error('Error creating Api Access Key'))
1919
}
2020

21-
export function getApiKeysForProject(projectId: number): Promise<SelectableApiKey[]> {
22-
return db.selectFrom('apikeys').selectAll().where('project_id', '==', projectId).execute()
21+
export function getApiAccessForProject(projectId: number): Promise<SelectableApiKey[]> {
22+
return db.selectFrom('apiaccess').selectAll().where('project_id', '==', projectId).execute()
2323
}
2424

25-
export async function setApiKeyName(keyId: number, name: string): Promise<void> {
25+
export async function setApiAccessName(keyId: number, name: string): Promise<void> {
2626
await db
27-
.updateTable('apikeys')
27+
.updateTable('apiaccess')
2828
.set({
2929
name
3030
})
3131
.where('id', '==', keyId)
3232
.execute()
3333
}
3434

35-
export async function projectHasKey(projectId: number, key: string): Promise<boolean> {
35+
export async function projectHasKey(projectId: number, apikey: string): Promise<boolean> {
3636
const result = await db
37-
.selectFrom('apikeys')
37+
.selectFrom('apiaccess')
3838
.selectAll()
3939
.where('project_id', '==', projectId)
40-
.where('key', '==', key)
40+
.where('apikey', '==', apikey)
4141
.execute()
4242

4343
return !!result.length
4444
}
4545

46-
export async function deleteApiKey(projectId: number, key: string): Promise<void> {
46+
export async function deleteApiAccess(projectId: number, apikey: string): Promise<void> {
4747
await db
48-
.deleteFrom('apikeys')
48+
.deleteFrom('apiaccess')
4949
.where('project_id', '==', projectId)
50-
.where('key', '==', key)
50+
.where('apikey', '==', apikey)
5151
.execute()
5252
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {
2+
createApiAccess,
3+
getApiAccessForProject,
4+
projectHasKey,
5+
setApiAccessName
6+
} from './api-access.repository'
7+
8+
export const checkApiKeyAccess = async (apiKey: string, projectId: number): Promise<boolean> => {
9+
return await projectHasKey(projectId, apiKey)
10+
}
11+
12+
export const addApiKey = async (projectId: number): Promise<string> => {
13+
const key = await createApiAccess(projectId)
14+
return key.apikey
15+
}
16+
17+
export const changeApiKeyName = async (apiAccessId: number, name: string) => {
18+
await setApiAccessName(apiAccessId, name)
19+
}
20+
21+
export const listApiKeys = async (projectId: number): Promise<string[]> => {
22+
const result = await getApiAccessForProject(projectId)
23+
return result.map((it) => it.apikey)
24+
}

services/src/auth/api-access.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { Insertable, Selectable } from 'kysely'
2+
import type { Apiaccess } from 'kysely-codegen'
3+
import { z } from 'zod'
4+
5+
export type ApiKeyCreationParams = Insertable<Omit<Apiaccess, 'id' | 'created_at'>>
6+
export type SelectableApiKey = Selectable<Apiaccess>
7+
8+
const apiKeyIdSchema = z.number().brand('api-access')
9+
export type ApiKeyId = z.infer<typeof apiKeyIdSchema>
10+
11+
const apiKeyKeySchema = z.string().uuid().brand('api-key')
12+
export type ApiKey = z.infer<typeof apiKeyKeySchema>
13+
14+
const apiAccessSchema = z.object({
15+
id: apiKeyIdSchema,
16+
apikey: apiKeyKeySchema,
17+
name: z.string(),
18+
project_id: z.number(),
19+
created_at: z.date(),
20+
updated_at: z.date()
21+
})
22+
export type ApiAccess = z.infer<typeof apiAccessSchema>

services/src/auth/api-key.service.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

services/src/auth/api-key.ts

Lines changed: 0 additions & 26 deletions
This file was deleted.

services/src/kysely/migrations/2024-05-16T19:00:00Z_apikey.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { Kysely } from 'kysely'
22
import { createTableMigration } from '../migration.util'
33

44
export async function up(db: Kysely<unknown>): Promise<void> {
5-
await createTableMigration(db, 'apikeys')
6-
.addColumn('key', 'text', (col) => col.unique().notNull())
5+
await createTableMigration(db, 'apiaccess')
6+
.addColumn('apikey', 'text', (col) => col.unique().notNull())
77
.addColumn('name', 'text')
88
.addColumn('project_id', 'integer', (col) =>
99
col.references('projects.id').onDelete('cascade').notNull()
@@ -12,5 +12,5 @@ export async function up(db: Kysely<unknown>): Promise<void> {
1212
}
1313

1414
export async function down(db: Kysely<unknown>): Promise<void> {
15-
await db.schema.dropTable('apikeys').execute()
15+
await db.schema.dropTable('apiaccess').execute()
1616
}

src/routes/(api)/api/[project]/[lang]/translations/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import { translationPOSTRequestSchema, type ProjectId } from '../../../api.model
44
import type { RequestHandler } from './$types'
55

66
export const POST: RequestHandler = async ({ params, request }) => {
7-
authorize(request, params.project as ProjectId)
7+
authorize(request, +params.project as ProjectId)
88
const newTranslations = validateRequestBody(request, translationPOSTRequestSchema)
99
return new Response(
1010
`getting POST for translations on project "${params.project}" and lang "${params.lang}" with body "${JSON.stringify(newTranslations)}"`
1111
)
1212
}
1313

1414
export const GET: RequestHandler = ({ params, request }) => {
15-
authorize(request, params.project as ProjectId)
15+
authorize(request, +params.project as ProjectId)
1616
return new Response(
1717
`getting GET for translations on project "${params.project}" and lang "${params.lang}"`
1818
)

src/routes/(api)/api/[project]/config/+server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { projectConfigPOSTRequestSchema, type ProjectId } from '../../api.model'
44
import type { RequestHandler } from './$types'
55

66
export const POST: RequestHandler = async ({ params, request }) => {
7-
authorize(request, params.project as ProjectId)
7+
authorize(request, +params.project as ProjectId)
88
const config = await validateRequestBody(request, projectConfigPOSTRequestSchema)
99

1010
return new Response(

0 commit comments

Comments
 (0)