Skip to content

Commit

Permalink
feat: return unique error message when using a blocked key (#1898)
Browse files Browse the repository at this point in the history
  • Loading branch information
e-schneid authored May 17, 2022
1 parent 4231216 commit 6fcd389
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 9 deletions.
10 changes: 10 additions & 0 deletions packages/api/src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ export class ErrorUserNotFound extends Error {
}
ErrorUserNotFound.CODE = 'ERROR_USER_NOT_FOUND'

export class ErrorTokenBlocked extends Error {
constructor(msg = 'API Key is blocked.') {
super(msg)
this.name = 'TokenBlocked'
this.status = 403
this.code = ErrorTokenBlocked.CODE
}
}
ErrorTokenBlocked.CODE = 'ERROR_TOKEN_BLOCKED'

export class ErrorTokenNotFound extends Error {
constructor(msg = 'API Key not found.') {
super(msg)
Expand Down
29 changes: 26 additions & 3 deletions packages/api/src/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,24 @@ import {
ErrorUserNotFound,
ErrorTokenNotFound,
ErrorUnauthenticated,
ErrorTokenBlocked,
} from '../errors.js'
import { parseJWT, verifyJWT } from './jwt.js'
export const magic = new Magic(secrets.magic)
import * as Ucan from 'ucan-storage/ucan-storage'

/**
*
* @param {import('./db-client-types.js').UserOutput} user
* @returns
*/
function filterDeletedKeys(user) {
return {
...user,
keys: user.keys.filter((k) => k.deleted_at === null),
}
}

/**
* Validate auth
*
Expand All @@ -27,7 +40,7 @@ export async function validate(event, { log, db, ucanService }, options) {
const user = await db.getUser(root.audience())
if (user) {
return {
user: user,
user: filterDeletedKeys(user),
db,
ucan: { token, root: root._decoded.payload, cap },
type: 'ucan',
Expand All @@ -45,11 +58,21 @@ export async function validate(event, { log, db, ucanService }, options) {
if (user) {
const key = user.keys.find((k) => k?.secret === token)
if (key) {
if (key.deleted_at) {
const isBlocked = await db.checkIfTokenBlocked(key)

if (isBlocked) {
throw new ErrorTokenBlocked()
} else {
throw new ErrorUserNotFound()
}
}

log.setUser({
id: user.id,
})
return {
user: user,
user: filterDeletedKeys(user),
key,
db,
type: 'key',
Expand All @@ -72,7 +95,7 @@ export async function validate(event, { log, db, ucanService }, options) {
})

return {
user,
user: filterDeletedKeys(user),
db,
type: 'session',
}
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/utils/db-client-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type UpsertUserInput = Pick<

export type UserOutputKey = Pick<
definitions['auth_key'],
'user_id' | 'id' | 'name' | 'secret'
'user_id' | 'id' | 'name' | 'secret' | 'deleted_at'
>

export type UserOutputTag = Pick<
Expand Down
23 changes: 20 additions & 3 deletions packages/api/src/utils/db-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,12 @@ export class DBClient {
magic_link_id,
github_id,
did,
keys:auth_key_user_id_fkey(user_id,id,name,secret),
keys:auth_key_user_id_fkey(user_id,id,name,secret,deleted_at),
tags:user_tag_user_id_fkey(user_id,id,tag,value)
`
)
.or(`magic_link_id.eq.${id},github_id.eq.${id},did.eq.${id}`)
// @ts-ignore
.filter('keys.deleted_at', 'is', null)
// @ts-ignore
.filter('tags.deleted_at', 'is', null)

const { data, error, status } = await select.single()
Expand All @@ -113,6 +111,25 @@ export class DBClient {
return data
}

/**
*
* @param {import('./db-client-types').UserOutputKey} key
*/
async checkIfTokenBlocked(key) {
const { data, error } = await this.client
.from('auth_key_history')
.select('status')
.eq('auth_key_id', key.id)
.filter('deleted_at', 'is', null)
.single()

if (error) {
throw new DBError(error)
}

return data?.status === 'Blocked'
}

/**
* Create upload with content and pins
*
Expand Down
4 changes: 2 additions & 2 deletions packages/api/test/db-client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('DB Client', () => {
client = await createClientWithUser()
})

it('getUser should list only active keys', async () => {
it('getUser should list all keys', async () => {
const issuer1 = `did:eth:0x73573${Date.now()}`
const token1 = await signJWT(
{
Expand Down Expand Up @@ -51,7 +51,7 @@ describe('DB Client', () => {
throw new Error('no user data')
}
const keys = user.keys
assert.equal(keys.length, 2)
assert.equal(keys.length, 3)
assert.equal(keys[1].name, 'key1')
})
})

0 comments on commit 6fcd389

Please sign in to comment.