Limit scope of API Keys (#989)
* first pass of disallowing certain APIs with API keys Disallow the following APIs: * item.act (zap) * create withdrawal * unlink auth method * link unverified email * disallow creating lnauths via API key to stop the flow of linking via lnauth * undo the limitation on donating to rewards * revert the assertion on createAuth * assert no api key on createWithdrawal and sendToLNAddr * incorporate PR feedback by adding API Key negative assertion to more mutations: * `createInvite` * `createAuth` * `upsertWalletLND` by way of `upsertWallet` * `upsertWalletLNAddr` by way of `upsertWallet`
This commit is contained in:
parent
0c0f303a11
commit
4b77e7a1a9
|
@ -0,0 +1,7 @@
|
|||
import { GraphQLError } from 'graphql'
|
||||
|
||||
export default function assertApiKeyNotPermitted ({ me }) {
|
||||
if (me?.apiKey === true) {
|
||||
throw new GraphQLError('this operation is not allowed to be performed via API Key', { extensions: { code: 'FORBIDDEN' } })
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { GraphQLError } from 'graphql'
|
||||
import { inviteSchema, ssValidate } from '@/lib/validate'
|
||||
import { msatsToSats } from '@/lib/format'
|
||||
import assertApiKeyNotPermitted from './apiKey'
|
||||
|
||||
export default {
|
||||
Query: {
|
||||
|
@ -32,6 +33,7 @@ export default {
|
|||
if (!me) {
|
||||
throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } })
|
||||
}
|
||||
assertApiKeyNotPermitted({ me })
|
||||
|
||||
await ssValidate(inviteSchema, { gift, limit })
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import { defaultCommentSort, isJob, deleteItemByAuthor, getDeleteCommand, hasDel
|
|||
import { datePivot, whenRange } from '@/lib/time'
|
||||
import { imageFeesInfo, uploadIdsFromText } from './image'
|
||||
import assertGofacYourself from './ofac'
|
||||
import assertApiKeyNotPermitted from './apiKey'
|
||||
|
||||
function commentsOrderByClause (me, models, sort) {
|
||||
if (sort === 'recent') {
|
||||
|
@ -856,6 +857,7 @@ export default {
|
|||
return id
|
||||
},
|
||||
act: async (parent, { id, sats, act = 'TIP', idempotent, hash, hmac }, { me, models, lnd, headers }) => {
|
||||
assertApiKeyNotPermitted({ me })
|
||||
await ssValidate(actSchema, { sats, act })
|
||||
await assertGofacYourself({ models, headers })
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { randomBytes } from 'crypto'
|
|||
import { bech32 } from 'bech32'
|
||||
import { GraphQLError } from 'graphql'
|
||||
import assertGofacYourself from './ofac'
|
||||
import assertApiKeyNotPermitted from './apiKey'
|
||||
|
||||
function encodedUrl (iurl, tag, k1) {
|
||||
const url = new URL(iurl)
|
||||
|
@ -26,7 +27,8 @@ export default {
|
|||
}
|
||||
},
|
||||
Mutation: {
|
||||
createAuth: async (parent, args, { models }) => {
|
||||
createAuth: async (parent, args, { models, me }) => {
|
||||
assertApiKeyNotPermitted({ me })
|
||||
return await models.lnAuth.create({ data: { k1: k1() } })
|
||||
},
|
||||
createWith: async (parent, args, { me, models, headers }) => {
|
||||
|
@ -36,6 +38,8 @@ export default {
|
|||
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
|
||||
}
|
||||
|
||||
assertApiKeyNotPermitted({ me })
|
||||
|
||||
return await models.lnWith.create({ data: { k1: k1(), userId: me.id } })
|
||||
}
|
||||
},
|
||||
|
|
|
@ -8,6 +8,7 @@ import { getItem, updateItem, filterClause, createItem, whereClause, muteClause
|
|||
import { ANON_USER_ID, DELETE_USER_ID, RESERVED_MAX_USER_ID, SN_NO_REWARDS_IDS } from '@/lib/constants'
|
||||
import { viewGroup } from './growth'
|
||||
import { whenRange } from '@/lib/time'
|
||||
import assertApiKeyNotPermitted from './apiKey'
|
||||
|
||||
const contributors = new Set()
|
||||
|
||||
|
@ -562,6 +563,7 @@ export default {
|
|||
if (!me) {
|
||||
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
|
||||
}
|
||||
assertApiKeyNotPermitted({ me })
|
||||
|
||||
let user
|
||||
if (authType === 'twitter' || authType === 'github') {
|
||||
|
@ -592,6 +594,7 @@ export default {
|
|||
if (!me) {
|
||||
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
|
||||
}
|
||||
assertApiKeyNotPermitted({ me })
|
||||
|
||||
await ssValidate(emailSchema, { email })
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import { LNDAutowithdrawSchema, amountSchema, lnAddrAutowithdrawSchema, lnAddrSc
|
|||
import { ANON_BALANCE_LIMIT_MSATS, ANON_INV_PENDING_LIMIT, ANON_USER_ID, BALANCE_LIMIT_MSATS, INVOICE_RETENTION_DAYS, INV_PENDING_LIMIT, USER_IDS_BALANCE_NO_LIMIT } from '@/lib/constants'
|
||||
import { datePivot } from '@/lib/time'
|
||||
import assertGofacYourself from './ofac'
|
||||
import assertApiKeyNotPermitted from './apiKey'
|
||||
|
||||
export async function getInvoice (parent, { id }, { me, models, lnd }) {
|
||||
const inv = await models.invoice.findUnique({
|
||||
|
@ -492,6 +493,7 @@ async function upsertWallet (
|
|||
if (!me) {
|
||||
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
|
||||
}
|
||||
assertApiKeyNotPermitted({ me })
|
||||
|
||||
await ssValidate(schema, { ...data, ...settings }, { me, models })
|
||||
|
||||
|
@ -562,6 +564,7 @@ async function upsertWallet (
|
|||
}
|
||||
|
||||
export async function createWithdrawal (parent, { invoice, maxFee }, { me, models, lnd, headers, autoWithdraw = false }) {
|
||||
assertApiKeyNotPermitted({ me })
|
||||
await ssValidate(withdrawlSchema, { invoice, maxFee })
|
||||
await assertGofacYourself({ models, headers })
|
||||
|
||||
|
@ -620,6 +623,7 @@ export async function sendToLnAddr (parent, { addr, amount, maxFee, comment, ...
|
|||
if (!me) {
|
||||
throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } })
|
||||
}
|
||||
assertApiKeyNotPermitted({ me })
|
||||
|
||||
const options = await lnAddrOptions(addr)
|
||||
await ssValidate(lnAddrSchema, { addr, amount, maxFee, comment, ...payer }, options)
|
||||
|
|
Loading…
Reference in New Issue