the reminder not showing content on the card at dashboard view and the quizes are hardcoded must move to the db make api's for it
179 lines
5.9 KiB
JavaScript
179 lines
5.9 KiB
JavaScript
const express = require('express');
|
|
const { Configuration, PlaidApi, PlaidEnvironments } = require('plaid');
|
|
const cors = require('cors');
|
|
require('dotenv').config();
|
|
|
|
const app = express();
|
|
|
|
// Enable CORS for all routes
|
|
app.use(cors());
|
|
app.use(express.json());
|
|
|
|
// Configure Plaid client
|
|
const configuration = new Configuration({
|
|
basePath: PlaidEnvironments[process.env.PLAID_ENV || 'sandbox'],
|
|
baseOptions: {
|
|
headers: {
|
|
'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
|
|
'PLAID-SECRET': process.env.PLAID_SECRET,
|
|
},
|
|
},
|
|
});
|
|
|
|
const plaidClient = new PlaidApi(configuration);
|
|
|
|
// Create a link token
|
|
app.post('/api/create_link_token', async (req, res) => {
|
|
try {
|
|
const tokenRequest = {
|
|
user: { client_user_id: req.body.userId || 'user-id' },
|
|
client_name: 'user_good',
|
|
products: ['auth', 'transactions'],
|
|
country_codes: ['US', 'CA'],
|
|
language: 'en'
|
|
};
|
|
|
|
console.log('Creating link token with request:', tokenRequest);
|
|
const createTokenResponse = await plaidClient.linkTokenCreate(tokenRequest);
|
|
console.log('Link token created:', createTokenResponse.data);
|
|
res.json(createTokenResponse.data);
|
|
} catch (error) {
|
|
console.error('Error creating link token:', error);
|
|
res.status(500).json({
|
|
error: error.message,
|
|
error_code: error.response?.data?.error_code,
|
|
error_type: error.response?.data?.error_type
|
|
});
|
|
}
|
|
});
|
|
|
|
// Exchange public token for access token
|
|
app.post('/api/exchange_public_token', async (req, res) => {
|
|
try {
|
|
if (!req.body.public_token) {
|
|
return res.status(400).json({
|
|
error: 'Missing public_token in request body'
|
|
});
|
|
}
|
|
|
|
console.log('Exchanging public token:', req.body.public_token);
|
|
const exchangeResponse = await plaidClient.itemPublicTokenExchange({
|
|
public_token: req.body.public_token
|
|
});
|
|
|
|
console.log('Token exchange successful:', exchangeResponse.data);
|
|
res.json({
|
|
access_token: exchangeResponse.data.access_token,
|
|
item_id: exchangeResponse.data.item_id,
|
|
});
|
|
} catch (error) {
|
|
console.error('Error exchanging public token:', error);
|
|
res.status(500).json({
|
|
error: error.message,
|
|
error_code: error.response?.data?.error_code,
|
|
error_type: error.response?.data?.error_type
|
|
});
|
|
}
|
|
});
|
|
|
|
// Get accounts
|
|
app.get('/api/accounts', async (req, res) => {
|
|
try {
|
|
const accessToken = req.headers['plaid-access-token'];
|
|
|
|
if (!accessToken) {
|
|
return res.status(400).json({
|
|
error: 'Missing access_token in request headers'
|
|
});
|
|
}
|
|
|
|
console.log('Getting accounts for access token:', accessToken);
|
|
const accountsResponse = await plaidClient.accountsGet({
|
|
access_token: accessToken
|
|
});
|
|
|
|
console.log('Got accounts:', accountsResponse.data);
|
|
res.json(accountsResponse.data);
|
|
} catch (error) {
|
|
console.error('Error getting accounts:', error);
|
|
res.status(500).json({
|
|
error: error.message,
|
|
error_code: error.response?.data?.error_code,
|
|
error_type: error.response?.data?.error_type
|
|
});
|
|
}
|
|
});
|
|
|
|
// Get transactions
|
|
app.get('/api/transactions', async (req, res) => {
|
|
try {
|
|
const accessToken = req.headers['plaid-access-token'];
|
|
|
|
if (!accessToken) {
|
|
return res.status(400).json({
|
|
error: 'Missing access_token in request headers'
|
|
});
|
|
}
|
|
|
|
// Get current date and date 30 days ago
|
|
const endDate = new Date().toISOString().slice(0, 10);
|
|
const startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
|
|
console.log('Getting transactions for access token:', accessToken);
|
|
|
|
// Initial request
|
|
const request = {
|
|
access_token: accessToken,
|
|
start_date: startDate,
|
|
end_date: endDate,
|
|
options: {
|
|
include_personal_finance_category: true,
|
|
count: 100,
|
|
offset: 0
|
|
}
|
|
};
|
|
|
|
let allTransactions = [];
|
|
const response = await plaidClient.transactionsGet(request);
|
|
let transactions = response.data.transactions;
|
|
const total_transactions = response.data.total_transactions;
|
|
allTransactions = allTransactions.concat(transactions);
|
|
|
|
// Handle pagination if there are more transactions
|
|
while (allTransactions.length < total_transactions) {
|
|
const paginatedRequest = {
|
|
access_token: accessToken,
|
|
start_date: startDate,
|
|
end_date: endDate,
|
|
options: {
|
|
include_personal_finance_category: true,
|
|
count: 100,
|
|
offset: allTransactions.length
|
|
}
|
|
};
|
|
const paginatedResponse = await plaidClient.transactionsGet(paginatedRequest);
|
|
allTransactions = allTransactions.concat(paginatedResponse.data.transactions);
|
|
}
|
|
|
|
console.log(`Got ${allTransactions.length} transactions`);
|
|
res.json({
|
|
transactions: allTransactions,
|
|
accounts: response.data.accounts,
|
|
item: response.data.item,
|
|
total_transactions: total_transactions,
|
|
request_id: response.data.request_id
|
|
});
|
|
} catch (error) {
|
|
console.error('Error getting transactions:', error);
|
|
res.status(500).json({
|
|
error: error.message,
|
|
error_code: error.response?.data?.error_code,
|
|
error_type: error.response?.data?.error_type
|
|
});
|
|
}
|
|
});
|
|
|
|
const PORT = process.env.PORT || 3000;
|
|
app.listen(PORT, () => {
|
|
console.log(`Server running on port ${PORT}`);
|
|
}); |