mirror of
https://github.com/MAGICGrants/campaign-site.git
synced 2026-01-09 12:27:59 -05:00
Use @t3-oss/env-nextjs for env variables
This commit is contained in:
11
.env.example
Normal file
11
.env.example
Normal file
@@ -0,0 +1,11 @@
|
||||
NEXTAUTH_SECRET=""
|
||||
STRIPE_SECRET_KEY=""
|
||||
KEYCLOAK_CLIENT_ID="app"
|
||||
KEYCLOAK_CLIENT_SECRET="7JryN6EVIYtCwN4iHheacjp986Rfy5FJ"
|
||||
KEYCLOAK_REALM_NAME="monerofund"
|
||||
BTCPAY_URL=""
|
||||
BTCPAY_STORE_ID=""
|
||||
BTCPAY_API_KEY=""
|
||||
SENDGRID_RECIPIENT=""
|
||||
SENDGRID_VERIFIED_SENDER=""
|
||||
SENDGRID_API_KEY=""
|
||||
25
env.mjs
25
env.mjs
@@ -8,7 +8,16 @@ export const env = createEnv({
|
||||
* Will throw if you access these variables on the client.
|
||||
*/
|
||||
server: {
|
||||
OPEN_AI_API_KEY: z.string().min(1),
|
||||
STRIPE_SECRET_KEY: z.string().min(1),
|
||||
KEYCLOAK_CLIENT_ID: z.string().min(1),
|
||||
KEYCLOAK_CLIENT_SECRET: z.string().min(1),
|
||||
KEYCLOAK_REALM_NAME: z.string().min(1),
|
||||
BTCPAY_URL: z.string().min(1),
|
||||
BTCPAY_STORE_ID: z.string().min(1),
|
||||
BTCPAY_API_KEY: z.string().min(1),
|
||||
SENDGRID_RECIPIENT: z.string().min(1),
|
||||
SENDGRID_VERIFIED_SENDER: z.string().min(1),
|
||||
SENDGRID_API_KEY: z.string().min(1),
|
||||
},
|
||||
/*
|
||||
* Environment variables available on the client (and server).
|
||||
@@ -25,9 +34,15 @@ export const env = createEnv({
|
||||
* 💡 You'll get type errors if not all variables from `server` & `client` are included here.
|
||||
*/
|
||||
runtimeEnv: {
|
||||
DATABASE_URL: process.env.DATABASE_URL,
|
||||
OPEN_AI_API_KEY: process.env.OPEN_AI_API_KEY,
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
|
||||
process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
|
||||
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
|
||||
KEYCLOAK_CLIENT_ID: process.env.KEYCLOAK_CLIENT_ID,
|
||||
KEYCLOAK_CLIENT_SECRET: process.env.KEYCLOAK_CLIENT_SECRET,
|
||||
KEYCLOAK_REALM_NAME: process.env.KEYCLOAK_REALM_NAME,
|
||||
BTCPAY_URL: process.env.BTCPAY_URL,
|
||||
BTCPAY_STORE_ID: process.env.BTCPAY_STORE_ID,
|
||||
BTCPAY_API_KEY: process.env.BTCPAY_API_KEY,
|
||||
SENDGRID_RECIPIENT: process.env.SENDGRID_RECIPIENT,
|
||||
SENDGRID_VERIFIED_SENDER: process.env.SENDGRID_VERIFIED_SENDER,
|
||||
SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,
|
||||
},
|
||||
})
|
||||
|
||||
34
package-lock.json
generated
34
package-lock.json
generated
@@ -22,7 +22,7 @@
|
||||
"@sendgrid/mail": "^8.1.3",
|
||||
"@stripe/react-stripe-js": "^2.7.1",
|
||||
"@stripe/stripe-js": "^3.4.1",
|
||||
"@t3-oss/env-nextjs": "^0.10.1",
|
||||
"@t3-oss/env-nextjs": "^0.7.3",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tanstack/react-query": "^5.40.1",
|
||||
@@ -3794,11 +3794,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@t3-oss/env-core": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.10.1.tgz",
|
||||
"integrity": "sha512-GcKZiCfWks5CTxhezn9k5zWX3sMDIYf6Kaxy2Gx9YEQftFcz8hDRN56hcbylyAO3t4jQnQ5ifLawINsNgCDpOg==",
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.7.3.tgz",
|
||||
"integrity": "sha512-hhtj59TKC6TKVdwJ0CcbKsvkr9R8Pc/SNKd4IgGUIC9T9X6moB8EZZ3FTJdABA/h9UABCK4J+KsF8gzmvMvHPg==",
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0",
|
||||
"typescript": ">=4.7.2",
|
||||
"zod": "^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
@@ -3808,14 +3808,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@t3-oss/env-nextjs": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.10.1.tgz",
|
||||
"integrity": "sha512-iy2qqJLnFh1RjEWno2ZeyTu0ufomkXruUsOZludzDIroUabVvHsrSjtkHqwHp1/pgPUzN3yBRHMILW162X7x2Q==",
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.7.3.tgz",
|
||||
"integrity": "sha512-90TNffS17vjkQwfYyMUb4Zw9yqHwFV40f78qFug4JiQa5+N6DydTdlLOpzOcj8Cna/qpAVDwMSypofF/TVQDuA==",
|
||||
"dependencies": {
|
||||
"@t3-oss/env-core": "0.10.1"
|
||||
"@t3-oss/env-core": "0.7.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0",
|
||||
"typescript": ">=4.7.2",
|
||||
"zod": "^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
@@ -13581,17 +13581,17 @@
|
||||
}
|
||||
},
|
||||
"@t3-oss/env-core": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.10.1.tgz",
|
||||
"integrity": "sha512-GcKZiCfWks5CTxhezn9k5zWX3sMDIYf6Kaxy2Gx9YEQftFcz8hDRN56hcbylyAO3t4jQnQ5ifLawINsNgCDpOg==",
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.7.3.tgz",
|
||||
"integrity": "sha512-hhtj59TKC6TKVdwJ0CcbKsvkr9R8Pc/SNKd4IgGUIC9T9X6moB8EZZ3FTJdABA/h9UABCK4J+KsF8gzmvMvHPg==",
|
||||
"requires": {}
|
||||
},
|
||||
"@t3-oss/env-nextjs": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.10.1.tgz",
|
||||
"integrity": "sha512-iy2qqJLnFh1RjEWno2ZeyTu0ufomkXruUsOZludzDIroUabVvHsrSjtkHqwHp1/pgPUzN3yBRHMILW162X7x2Q==",
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.7.3.tgz",
|
||||
"integrity": "sha512-90TNffS17vjkQwfYyMUb4Zw9yqHwFV40f78qFug4JiQa5+N6DydTdlLOpzOcj8Cna/qpAVDwMSypofF/TVQDuA==",
|
||||
"requires": {
|
||||
"@t3-oss/env-core": "0.10.1"
|
||||
"@t3-oss/env-core": "0.7.3"
|
||||
}
|
||||
},
|
||||
"@tailwindcss/aspect-ratio": {
|
||||
|
||||
@@ -99,4 +99,4 @@
|
||||
"extensions": "js,jsx,tsx,ts,css,scss,md"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,14 @@ import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { CURRENCY, MIN_AMOUNT } from '../../config'
|
||||
import { fetchPostJSONAuthed } from '../../utils/api-helpers'
|
||||
import { PayReq } from '../../utils/types'
|
||||
|
||||
import { env } from '../../env.mjs'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
if (req.method === 'POST') {
|
||||
const { amount, project_name, project_slug, email, name }: PayReq =
|
||||
req.body
|
||||
const { amount, project_name, project_slug, email, name }: PayReq = req.body
|
||||
const REDIRECT = 'http://monerofund.org/thankyou'
|
||||
|
||||
try {
|
||||
@@ -28,12 +27,11 @@ export default async function handler(
|
||||
}
|
||||
|
||||
let data = await fetchPostJSONAuthed(
|
||||
`${process.env.BTCPAY_URL!}stores/${process.env.BTCPAY_STORE_ID
|
||||
}/invoices`,
|
||||
`token ${process.env.BTCPAY_API_KEY}`,
|
||||
`${env.BTCPAY_URL}stores/${env.BTCPAY_STORE_ID}/invoices`,
|
||||
`token ${env.BTCPAY_API_KEY}`,
|
||||
{
|
||||
amount: amount,
|
||||
currency: "USD",
|
||||
currency: 'USD',
|
||||
metadata: {
|
||||
orderId: project_slug,
|
||||
project_name,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next/types'
|
||||
import { env } from '../../env.mjs'
|
||||
|
||||
const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY
|
||||
const TO_ADDRESS = process.env.SENDGRID_RECEPIENT
|
||||
const FROM_ADDRESS = process.env.SENDGRID_VERIFIED_SENDER
|
||||
const SENDGRID_API_KEY = env.SENDGRID_API_KEY
|
||||
const TO_ADDRESS = env.SENDGRID_RECIPIENT
|
||||
const FROM_ADDRESS = env.SENDGRID_VERIFIED_SENDER
|
||||
|
||||
const sgMail = require('@sendgrid/mail')
|
||||
sgMail.setApiKey(SENDGRID_API_KEY)
|
||||
@@ -23,7 +24,7 @@ export default async function handler(
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(process.env.SENDGRID_API_KEY)
|
||||
console.log(env.SENDGRID_API_KEY)
|
||||
const msg = {
|
||||
to: TO_ADDRESS, // Change to your recipient
|
||||
from: FROM_ADDRESS, // Change to your verified sender
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import Stripe from 'stripe'
|
||||
|
||||
import { CURRENCY, MIN_AMOUNT } from '../../config'
|
||||
// import { formatAmountForStripe } from '../../utils/stripe-helpers'
|
||||
|
||||
import Stripe from 'stripe'
|
||||
import { PayReq } from '../../utils/types'
|
||||
import { env } from '../../env.mjs'
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||
const stripe = new Stripe(env.STRIPE_SECRET_KEY, {
|
||||
// https://github.com/stripe/stripe-node#configuration
|
||||
apiVersion: "2024-04-10",
|
||||
apiVersion: '2024-04-10',
|
||||
})
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const { amount, project_name, project_slug, email, name }: PayReq =
|
||||
req.body
|
||||
|
||||
const { amount, project_name, project_slug, email, name }: PayReq = req.body
|
||||
|
||||
if (req.method === 'POST') {
|
||||
try {
|
||||
@@ -37,7 +36,7 @@ export default async function handler(
|
||||
product_data: {
|
||||
name: `MAGIC Grants donation: ${project_name}`,
|
||||
},
|
||||
unit_amount: amount*100,
|
||||
unit_amount: amount * 100,
|
||||
},
|
||||
quantity: 1,
|
||||
},
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { keycloak } from '../services'
|
||||
import { env } from '../../env.mjs'
|
||||
|
||||
export const authenticateKeycloakClient = () =>
|
||||
keycloak.auth({
|
||||
clientId: 'app',
|
||||
clientSecret: '7JryN6EVIYtCwN4iHheacjp986Rfy5FJ',
|
||||
clientId: env.KEYCLOAK_CLIENT_ID,
|
||||
clientSecret: env.KEYCLOAK_CLIENT_SECRET,
|
||||
grantType: 'client_credentials',
|
||||
})
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { env } from '../env.mjs'
|
||||
|
||||
export async function fetchGetJSON(url: string) {
|
||||
try {
|
||||
const data = await fetch(url).then((res) => res.json())
|
||||
@@ -20,7 +22,7 @@ export async function fetchPostJSON(url: string, data?: {}) {
|
||||
credentials: 'same-origin', // include, *same-origin, omit
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `token ${process.env.BTCPAY_API_KEY}`,
|
||||
Authorization: `token ${env.BTCPAY_API_KEY}`,
|
||||
},
|
||||
redirect: 'follow', // manual, *follow, error
|
||||
referrerPolicy: 'no-referrer', // no-referrer, *client
|
||||
@@ -58,19 +60,17 @@ export async function fetchPostJSONAuthed(
|
||||
})
|
||||
return await response.json() // parses JSON response into native JavaScript objects
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
if (err instanceof Error) {
|
||||
throw new Error(err.message)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchGetJSONAuthedBTCPay(
|
||||
slug: string
|
||||
) {
|
||||
export async function fetchGetJSONAuthedBTCPay(slug: string) {
|
||||
try {
|
||||
const url = `${process.env.BTCPAY_URL!}stores/${process.env.BTCPAY_STORE_ID}/invoices`
|
||||
const auth = `token ${process.env.BTCPAY_API_KEY}`
|
||||
const url = `${env.BTCPAY_URL}stores/${env.BTCPAY_STORE_ID}/invoices`
|
||||
const auth = `token ${env.BTCPAY_API_KEY}`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -85,13 +85,16 @@ export async function fetchGetJSONAuthedBTCPay(
|
||||
let totaldonationsbtc = 0
|
||||
let totaldonationsinfiatxmr = 0
|
||||
let totaldonationsinfiatbtc = 0
|
||||
for(let i=0;i<data.length;i++){
|
||||
if (data[i].metadata.orderId != slug && data[i].metadata.orderId != `${slug}_STATIC`) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (
|
||||
data[i].metadata.orderId != slug &&
|
||||
data[i].metadata.orderId != `${slug}_STATIC`
|
||||
) {
|
||||
continue
|
||||
}
|
||||
const id = data[i].id
|
||||
const urliter = `${process.env.BTCPAY_URL!}stores/${process.env.BTCPAY_STORE_ID}/invoices/${id}/payment-methods`
|
||||
const authiter = `token ${process.env.BTCPAY_API_KEY}`
|
||||
const urliter = `${env.BTCPAY_URL}stores/${env.BTCPAY_STORE_ID}/invoices/${id}/payment-methods`
|
||||
const authiter = `token ${env.BTCPAY_API_KEY}`
|
||||
const responseiter = await fetch(urliter, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -99,16 +102,24 @@ export async function fetchGetJSONAuthedBTCPay(
|
||||
Authorization: authiter,
|
||||
},
|
||||
})
|
||||
const dataiter = await responseiter.json();
|
||||
if (dataiter[1].cryptoCode == 'XMR' && dataiter[1].paymentMethodPaid > 0) {
|
||||
const dataiter = await responseiter.json()
|
||||
if (
|
||||
dataiter[1].cryptoCode == 'XMR' &&
|
||||
dataiter[1].paymentMethodPaid > 0
|
||||
) {
|
||||
numdonationsxmr += dataiter[1].payments.length
|
||||
totaldonationsxmr += Number(dataiter[1].paymentMethodPaid)
|
||||
totaldonationsinfiatxmr += Number(dataiter[1].paymentMethodPaid) * Number(dataiter[1].rate)
|
||||
totaldonationsinfiatxmr +=
|
||||
Number(dataiter[1].paymentMethodPaid) * Number(dataiter[1].rate)
|
||||
}
|
||||
if (dataiter[0].cryptoCode == 'BTC' && dataiter[0].paymentMethodPaid > 0) {
|
||||
if (
|
||||
dataiter[0].cryptoCode == 'BTC' &&
|
||||
dataiter[0].paymentMethodPaid > 0
|
||||
) {
|
||||
numdonationsbtc += dataiter[0].payments.length
|
||||
totaldonationsbtc += Number(dataiter[0].paymentMethodPaid)
|
||||
totaldonationsinfiatbtc += Number(dataiter[0].paymentMethodPaid) * Number(dataiter[0].rate)
|
||||
totaldonationsinfiatbtc +=
|
||||
Number(dataiter[0].paymentMethodPaid) * Number(dataiter[0].rate)
|
||||
}
|
||||
}
|
||||
return await {
|
||||
@@ -121,8 +132,8 @@ export async function fetchGetJSONAuthedBTCPay(
|
||||
numdonations: numdonationsbtc,
|
||||
totaldonationsinfiat: totaldonationsinfiatbtc,
|
||||
totaldonations: totaldonationsbtc,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
throw new Error(err.message)
|
||||
@@ -131,12 +142,10 @@ export async function fetchGetJSONAuthedBTCPay(
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchGetJSONAuthedStripe(
|
||||
slug: string
|
||||
) {
|
||||
export async function fetchGetJSONAuthedStripe(slug: string) {
|
||||
try {
|
||||
const url = "https://api.stripe.com/v1/charges"
|
||||
const auth = `Bearer ${process.env.STRIPE_SECRET_KEY}`
|
||||
const url = 'https://api.stripe.com/v1/charges'
|
||||
const auth = `Bearer ${env.STRIPE_SECRET_KEY}`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -148,14 +157,21 @@ export async function fetchGetJSONAuthedStripe(
|
||||
const dataext = data.data
|
||||
let total = 0
|
||||
let donations = 0
|
||||
for(let i=0;i<dataext.length;i++){
|
||||
if (dataext[i].metadata.project_slug == null || dataext[i].metadata.project_slug != slug) {
|
||||
for (let i = 0; i < dataext.length; i++) {
|
||||
if (
|
||||
dataext[i].metadata.project_slug == null ||
|
||||
dataext[i].metadata.project_slug != slug
|
||||
) {
|
||||
continue
|
||||
}
|
||||
total += Number(dataext[i].amount) / 100
|
||||
donations += 1
|
||||
}
|
||||
return await { numdonations: donations, totaldonationsinfiat: total, totaldonations: total }
|
||||
return await {
|
||||
numdonations: donations,
|
||||
totaldonationsinfiat: total,
|
||||
totaldonations: total,
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
throw new Error(err.message)
|
||||
|
||||
Reference in New Issue
Block a user