Skip to content

Commit ba3675f

Browse files
committed
Only authorized users can pay bonuses
1 parent b8f33b5 commit ba3675f

File tree

5 files changed

+71
-62
lines changed

5 files changed

+71
-62
lines changed

.env.example

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ BTCPAYSERVER_WALLET_ID=
2121
BTCPAYSERVER_SECRET=
2222
OAUTH_REDIRECT_NEW_USERS=
2323
OAUTH_REDIRECT_EXISTING_USERS=
24+
TEMP_AUTHORIZED_SUPERUSER_ID=
2425

2526
# Frontend environment variables (/src)
2627
# require `REACT_APP_` prefix

api/config/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require('dotenv').config()
22

33
module.exports = {
4+
TEMP_AUTHORIZED_SUPERUSER_ID: process.env.TEMP_AUTHORIZED_SUPERUSER_ID,
45
GITHUB_OAUTH_URL: 'https://github.com/login/oauth/access_token',
56
INVOICELY_CSV_PATH: `${process.env.INVOICELY_CSV_PATH}`,
67
SITE_ROOT: process.env.NODE_ENV == 'production'

api/schema/resolvers/PaymentResolver.js

+65-61
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const bitcoinConversion = require('bitcoin-conversion')
55

66
const { validateDatesFormat } = require('../helpers/inputValidation')
77
const apiModules = require('../../modules')
8-
const { DEFAULT_STRIPE_CURRENCY, STRIPE_SUPPORTED_CURRENCIES } = require('../../config/constants')
8+
const { DEFAULT_STRIPE_CURRENCY, STRIPE_SUPPORTED_CURRENCIES, TEMP_AUTHORIZED_SUPERUSER_ID } = require('../../config/constants')
99
const lnd = require('../../handlers/lnd')
1010
const btcPayServer = require('../../handlers/btcPayServer')
1111

@@ -152,74 +152,78 @@ module.exports = {
152152
throw new Error('Failed to convert USD to SATS: ', error);
153153
}
154154
},
155-
sendPayment: async (root, { contributors }, { models }) => {
156-
const results = []
157-
const onChainAddresses = []
158-
159-
const contributorIds = contributors.map(c => c.id)
160-
const amounts = contributors.map(c => c.amount)
161-
162-
const reflect = promise => promise.then(
163-
value => ({ status: 'fulfilled', value }),
164-
error => ({ status: 'rejected', reason: error })
165-
)
166-
167-
const wallets = await models.Wallet.findAll({
168-
where: {
169-
contributor_id: contributorIds
155+
sendPayment: async (root, { contributors }, { cookies, models }) => {
156+
if (cookies.userSession === TEMP_AUTHORIZED_SUPERUSER_ID) {
157+
const results = []
158+
const onChainAddresses = []
159+
160+
const contributorIds = contributors.map(c => c.id)
161+
const amounts = contributors.map(c => c.amount)
162+
163+
const reflect = promise => promise.then(
164+
value => ({ status: 'fulfilled', value }),
165+
error => ({ status: 'rejected', reason: error })
166+
)
167+
168+
const wallets = await models.Wallet.findAll({
169+
where: {
170+
contributor_id: contributorIds
171+
}
172+
})
173+
174+
const invoices = await Promise.all(wallets.map(async (wallet, i) => {
175+
if (wallet.dataValues.invoice_macaroon) {
176+
const invoice = await lnd.addInvoice(wallet.dataValues.lnd_host, wallet.dataValues.lnd_port, wallet.dataValues.invoice_macaroon, amounts[i])
177+
return invoice.payment_request
178+
} else {
179+
onChainAddresses.push({
180+
address: wallet.dataValues.onchain_address,
181+
amount: amounts[i]
182+
})
183+
return null
184+
}
185+
}))
186+
187+
if (invoices) {
188+
const lndInvoices = invoices.filter(invoice => invoice !== null)
189+
190+
const payLndInvoices = async () => lndInvoices.map(async invoice => {
191+
return reflect(btcPayServer.payLightningInvoice(invoice))
192+
.then(result => {
193+
return result.status === 'fulfilled' ? result.value : { error: result.reason.message, status: result.status }
194+
})
195+
})
196+
const lndInvocesResults = await Promise.all(await payLndInvoices())
197+
results.push(...lndInvocesResults)
170198
}
171-
})
172-
173-
const invoices = await Promise.all(wallets.map(async (wallet, i) => {
174-
if (wallet.dataValues.invoice_macaroon) {
175-
const invoice = await lnd.addInvoice(wallet.dataValues.lnd_host, wallet.dataValues.lnd_port, wallet.dataValues.invoice_macaroon, amounts[i])
176-
return invoice.payment_request
177-
} else {
178-
onChainAddresses.push({
179-
address: wallet.dataValues.onchain_address,
180-
amount: amounts[i]
199+
200+
if (onChainAddresses) {
201+
const payOnChain = async () => onChainAddresses.map(async receiver => {
202+
return reflect(btcPayServer.createOnChainTransaction(receiver.address, String(receiver.amount / 100000000)))
203+
.then(result => {
204+
return result.status === 'fulfilled' ? result.value : { error: result.reason.message, status: result.status }
205+
})
181206
})
182-
return null
207+
const onChainResults = await Promise.all(await payOnChain())
208+
results.push(...onChainResults)
183209
}
184-
}))
185-
186-
if (invoices) {
187-
const lndInvoices = invoices.filter(invoice => invoice !== null)
188210

189-
const payLndInvoices = async () => lndInvoices.map(async invoice => {
190-
return reflect(btcPayServer.payLightningInvoice(invoice))
191-
.then(result => {
192-
return result.status === 'fulfilled' ? result.value : { error: result.reason.message, status: result.status }
193-
})
194-
})
195-
const lndInvocesResults = await Promise.all(await payLndInvoices())
196-
results.push(...lndInvocesResults)
197-
}
198-
199-
if (onChainAddresses) {
200-
const payOnChain = async () => onChainAddresses.map(async receiver => {
201-
return reflect(btcPayServer.createOnChainTransaction(receiver.address, String(receiver.amount / 100000000)))
202-
.then(result => {
203-
return result.status === 'fulfilled' ? result.value : { error: result.reason.message, status: result.status }
211+
results.map(result => {
212+
if (result && !result.error) {
213+
models.Payment.create({
214+
amount: result.paymentRequest ? result.amount / 1000 : result.amount,
215+
external_uuid: result.paymentRequest ? result.paymentRequest : result.transactionHash,
216+
date_incurred: moment.unix(result.createdAt ? result.createdAt : result.timestamp).utc().format('YYYY-MM-DD'),
217+
external_uuid_type: 'bitcoin',
218+
currency: 'SATS'
204219
})
220+
}
205221
})
206-
const onChainResults = await Promise.all(await payOnChain())
207-
results.push(...onChainResults)
222+
return results
223+
} else {
224+
throw new Error('Unathorized user')
208225
}
209226

210-
results.map(result => {
211-
if (result && !result.error) {
212-
models.Payment.create({
213-
amount: result.paymentRequest ? result.amount / 1000 : result.amount,
214-
external_uuid: result.paymentRequest ? result.paymentRequest : result.transactionHash,
215-
date_incurred: moment.unix(result.createdAt ? result.createdAt : result.timestamp).utc().format('YYYY-MM-DD'),
216-
external_uuid_type: 'bitcoin',
217-
currency: 'SATS'
218-
})
219-
}
220-
})
221-
222-
return results
223227
}
224228
}
225229

srcv2/constants/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const API_ROOT = process.env.REACT_APP_API_URL
2+
export const TEMP_AUTHORIZED_SUPERUSER_ID = process.env.TEMP_AUTHORIZED_SUPERUSER_ID
23
export const IS_PRODUCTION = process.env.NODE_ENV == 'production' ? true : false
34
export const GITHUB_LOGO_URL = 'https://project-trinary.s3.us-east-1.amazonaws.com/images/github-icon.png'
45
export const GITHUB_ALT_LOGO_URL = 'https://setlife-solutions.s3.us-east-1.amazonaws.com/images/github-alt-logo.png'

srcv2/pages/ProjectDetailPage.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { getHandle, selectCurrencyInformation } from '../scripts/selectors'
1717

1818
import { sessionUser } from '../reactivities/variables'
1919

20+
import { TEMP_AUTHORIZED_SUPERUSER_ID } from '../constants'
21+
2022
const ProjectDetailPage = (props) => {
2123

2224
const { projectId } = useParams()
@@ -181,7 +183,7 @@ const ProjectDetailPage = (props) => {
181183
Active Contributors
182184
</p>
183185
</div>
184-
{sessionUser().wallet && sessionUser().wallet.invoice_macaroon && sessionUser().github_handle.split('/')[3] == 'otech47' &&
186+
{sessionUser().id === TEMP_AUTHORIZED_SUPERUSER_ID &&
185187
<button
186188
type='button'
187189
className='border-2 border-setlife text-setlife rounded-full py-1 mb-4 w-fit h-fit px-2 ml-auto'

0 commit comments

Comments
 (0)