Skip to content

Commit

Permalink
Update keys method v0.28
Browse files Browse the repository at this point in the history
  • Loading branch information
bidoubiwa committed Jun 20, 2022
1 parent 6801047 commit 02dadae
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 41 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,11 +626,11 @@ Using the index object:

- [Create a key](https://docs.meilisearch.com/reference/api/keys.html#create-a-key):

`client.createKey(options: KeyPayload): Promise<Key>`
`client.createKey(options: KeyCreation): Promise<Key>`

- [Update a key](https://docs.meilisearch.com/reference/api/keys.html#update-a-key):

`client.updateKey(key: string, options: KeyPayload): Promise<Key>`
`client.updateKey(key: string, options: KeyUpdate): Promise<Key>`

- [Delete a key](https://docs.meilisearch.com/reference/api/keys.html#delete-a-key):

Expand Down
17 changes: 9 additions & 8 deletions src/clients/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import { Index } from '../indexes'
import {
KeyPayload,
KeyCreation,
Config,
IndexOptions,
IndexResponse,
Expand All @@ -26,6 +26,7 @@ import {
TokenOptions,
TaskParams,
WaitOptions,
KeyUpdate,
} from '../types'
import { HttpRequests } from '../http-requests'
import { TaskClient } from '../task'
Expand Down Expand Up @@ -257,11 +258,11 @@ class Client {
* @memberof MeiliSearch
* @method getKey
*
* @param {string} key - Key
* @param {string} keyOrUid - Key or uid of the API key
* @returns {Promise<Keys>} Promise returning a key
*/
async getKey(key: string): Promise<Key> {
const url = `keys/${key}`
async getKey(keyOrUid: string): Promise<Key> {
const url = `keys/${keyOrUid}`
return await this.httpRequest.get<Key>(url)
}

Expand All @@ -270,10 +271,10 @@ class Client {
* @memberof MeiliSearch
* @method createKey
*
* @param {KeyPayload} options - Key options
* @param {KeyCreation} options - Key options
* @returns {Promise<Key>} Promise returning an object with keys
*/
async createKey(options: KeyPayload): Promise<Key> {
async createKey(options: KeyCreation): Promise<Key> {
const url = `keys`
return await this.httpRequest.post(url, options)
}
Expand All @@ -284,10 +285,10 @@ class Client {
* @method updateKey
*
* @param {string} key - Key
* @param {KeyPayload} options - Key options
* @param {KeyUpdate} options - Key options
* @returns {Promise<Key>} Promise returning an object with keys
*/
async updateKey(key: string, options: KeyPayload): Promise<Key> {
async updateKey(key: string, options: KeyUpdate): Promise<Key> {
const url = `keys/${key}`
return await this.httpRequest.patch(url, options)
}
Expand Down
11 changes: 10 additions & 1 deletion src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,9 @@ export type Stats = {
*/

export type Key = {
uid: string
description: string
name: string | null
key: string
actions: string[]
indexes: string[]
Expand All @@ -306,13 +308,20 @@ export type Key = {
updateAt: string
}

export type KeyPayload = {
export type KeyCreation = {
uid?: string
name?: string
description?: string
actions: string[]
indexes: string[]
expiresAt: string | null
}

export type KeyUpdate = {
name?: string
description?: string
}

/*
** version
*/
Expand Down
74 changes: 44 additions & 30 deletions tests/keys.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ErrorStatusCode, Key } from '../src/types'
import { ErrorStatusCode } from '../src/types'
import {
clearAllIndexes,
config,
Expand All @@ -12,36 +12,49 @@ beforeEach(async () => {

describe.each([{ permission: 'Master' }])('Test on keys', ({ permission }) => {
beforeEach(async () => {
const client = await getClient('Master')
await clearAllIndexes(config)

const keys = await client.getKeys()

const customKeys = keys.results.filter(
(key) =>
key.name !== 'Default Search API Key' &&
key.name !== 'Default Admin API Key'
)

// Delete all custom keys
await Promise.all(customKeys.map((key) => client.deleteKey(key.uid)))
})

test(`${permission} key: get keys`, async () => {
const client = await getClient(permission)
const { results: keys } = await client.getKeys()

const defaultKey = keys.find((key: Key) =>
key.description.startsWith('Default Search API')
const searchKey = keys.find(
(key: any) => key.name === 'Default Search API Key'
)

expect(defaultKey).toBeDefined()
expect(defaultKey).toHaveProperty(
expect(searchKey).toBeDefined()
expect(searchKey).toHaveProperty(
'description',
'Default Search API Key (Use it to search from the frontend)'
'Use it to search from the frontend'
)
expect(defaultKey).toHaveProperty('key')
expect(defaultKey).toHaveProperty('actions')
expect(defaultKey).toHaveProperty('indexes')
expect(defaultKey).toHaveProperty('expiresAt', null)
expect(defaultKey).toHaveProperty('createdAt')
expect(defaultKey).toHaveProperty('updatedAt')

const adminKey = keys.find((key: Key) =>
key.description.startsWith('Default Admin API Key')
expect(searchKey).toHaveProperty('key')
expect(searchKey).toHaveProperty('actions')
expect(searchKey).toHaveProperty('indexes')
expect(searchKey).toHaveProperty('expiresAt', null)
expect(searchKey).toHaveProperty('createdAt')
expect(searchKey).toHaveProperty('updatedAt')

const adminKey = keys.find(
(key: any) => key.name === 'Default Admin API Key'
)

expect(adminKey).toBeDefined()
expect(adminKey).toHaveProperty(
'description',
'Default Admin API Key (Use it for all other operations. Caution! Do not use it on a public frontend)'
'Use it for anything that is not a search operation. Caution! Do not expose it on a public frontend'
)
expect(adminKey).toHaveProperty('key')
expect(adminKey).toHaveProperty('actions')
Expand All @@ -60,7 +73,7 @@ describe.each([{ permission: 'Master' }])('Test on keys', ({ permission }) => {
expect(key).toBeDefined()
expect(key).toHaveProperty(
'description',
'Default Admin API Key (Use it for all other operations. Caution! Do not use it on a public frontend)'
'Use it for anything that is not a search operation. Caution! Do not expose it on a public frontend'
)
expect(key).toHaveProperty('key')
expect(key).toHaveProperty('actions')
Expand All @@ -72,8 +85,10 @@ describe.each([{ permission: 'Master' }])('Test on keys', ({ permission }) => {

test(`${permission} key: create key with no expiresAt`, async () => {
const client = await getClient(permission)
const uid = '3db051e0-423d-4b5c-a63a-f82a7043dce6'

const key = await client.createKey({
uid,
description: 'Indexing Products API key',
actions: ['documents.add'],
indexes: ['products'],
Expand All @@ -82,6 +97,7 @@ describe.each([{ permission: 'Master' }])('Test on keys', ({ permission }) => {

expect(key).toBeDefined()
expect(key).toHaveProperty('description', 'Indexing Products API key')
expect(key).toHaveProperty('uid', uid)
expect(key).toHaveProperty('key')
expect(key).toHaveProperty('actions')
expect(key).toHaveProperty('indexes')
Expand Down Expand Up @@ -121,23 +137,16 @@ describe.each([{ permission: 'Master' }])('Test on keys', ({ permission }) => {
})

const updatedKey = await client.updateKey(key.key, {
description: 'Indexing Products API key',
actions: ['documents.add'],
indexes: ['products'],
expiresAt: '2050-11-13T00:00:00Z', // Test will fail in 2050
description: 'Indexing Products API key 2',
name: 'Product admin',
})

expect(updatedKey).toBeDefined()
expect(updatedKey).toHaveProperty(
'description',
'Indexing Products API key'
'Indexing Products API key 2'
)
expect(updatedKey).toHaveProperty('key')
expect(updatedKey).toHaveProperty('actions')
expect(updatedKey).toHaveProperty('indexes')
expect(updatedKey).toHaveProperty('expiresAt', '2050-11-13T00:00:00Z')
expect(updatedKey).toHaveProperty('createdAt')
expect(updatedKey).toHaveProperty('updatedAt')
expect(updatedKey).toHaveProperty('name', 'Product admin')
})

test(`${permission} key: delete a key`, async () => {
Expand All @@ -151,23 +160,28 @@ describe.each([{ permission: 'Master' }])('Test on keys', ({ permission }) => {
})

const deletedKey = await client.deleteKey(key.key)

expect(deletedKey).toBeUndefined()
})
})

describe.each([{ permission: 'Private' }])(
'Test on keys with admin key',
({ permission }) => {
test(`${permission} key: get keys denied`, async () => {
// TODO: unskip when fixed by Meilisearch
test.skip(`${permission} key: get keys denied`, async () => {
const client = await getClient(permission)

await expect(client.getKeys()).rejects.toHaveProperty(
'code',
ErrorStatusCode.INVALID_API_KEY
)
})

test(`${permission} key: create key denied`, async () => {
// TODO: unskip when fixed by Meilisearch
test.skip(`${permission} key: create key denied`, async () => {
const client = await getClient(permission)

await expect(
client.createKey({
description: 'Indexing Products API key',
Expand Down

0 comments on commit 02dadae

Please sign in to comment.