-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
167 lines (145 loc) · 5.09 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
require("dotenv").config();
require("express-async-errors");
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const { Configuration, PlaidApi, PlaidEnvironments } = require("plaid");
const app = express();
const moment = require("moment");
const cors = require('cors')
const APP_PORT = process.env.APP_PORT || 8081;
app.use(cors("*"));
// Creates a session key, which we can use to store the user's access token
// (Convenient for demo purposes, bad for a production-level app)
app.use(
session({
secret: process.env.SESSION_SECRET,
saveUninitialized: true,
resave: true,
})
);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));
const server = app.listen(APP_PORT, function () {
console.log(
`We're up and running. Head on over to http://localhost:${APP_PORT}/`
);
});
// Configuration for the Plaid client
const config = new Configuration({
basePath: PlaidEnvironments[process.env.PLAID_ENV],
baseOptions: {
headers: {
"PLAID-CLIENT-ID": process.env.PLAID_CLIENT_ID,
"PLAID-SECRET": process.env.PLAID_SECRET,
"Plaid-Version": "2020-09-14",
},
},
});
//Instantiate the Plaid client with the configuration
const client = new PlaidApi(config);
// Checks whether or not the user has an access token for a financial
// institution
app.get("/api/is_user_connected", async (req, res, next) => {
console.log(`Our access token: ${req.session.access_token}`);
return req.session.access_token
? res.json({ status: true })
: res.json({ status: false });
});
// Retrieves the name of the bank that we're connected to
app.get("/api/get_bank_name", async (req, res, next) => {
const access_token = req.session.access_token;
let itemResponse;
itemResponse = await client.itemGet({ access_token });
const configs = {
institution_id: itemResponse.data.item.institution_id,
country_codes: ["US"],
};
const instResponse = await client.institutionsGetById(configs);
console.log(`Institution Info: ${JSON.stringify(instResponse.data)}`);
const bankName = instResponse.data.institution.name;
res.json({ name: bankName });
});
//Creates a Link token and returns it
app.get("/api/create_link_token", async (req, res, next) => {
const tokenResponse = await client.linkTokenCreate({
user: { client_user_id: req.sessionID },
client_name: "Vanilla JavaScript Sample",
language: "en",
products: ["transactions"],
country_codes: ["US"],
redirect_uri: `http://localhost:${APP_PORT}/oauth-return.html`,
});
console.log(`Token response: ${JSON.stringify(tokenResponse.data)}`);
res.json(tokenResponse.data);
});
// Exchanges the public token from Plaid Link for an access token
app.post("/api/exchange_public_token", async (req, res, next) => {
const exchangeResponse = await client.itemPublicTokenExchange({
public_token: req.body.public_token,
});
// FOR DEMO PURPOSES ONLY
// You should really store access tokens in a database that's tied to your
// authenticated user id.
console.log(`Exchange response: ${JSON.stringify(exchangeResponse.data)}`);
req.session.access_token = exchangeResponse.data.access_token;
res.json(true);
});
// Fetches balance data using the Node client library for Plaid
app.get("/api/transactions", async (req, res, next) => {
const access_token = req.session.access_token;
const startDate = moment().subtract(30, "days").format("YYYY-MM-DD");
const endDate = moment().format("YYYY-MM-DD");
const transactionResponse = await client.transactionsGet({
access_token: access_token,
start_date: startDate,
end_date: endDate,
options: { count: 10 },
});
res.json(transactionResponse.data);
});
// Retrieve real-time Balances for each of an Item's accounts
// https://plaid.com/docs/#balance
app.get("/api/balance", async (req, res, next) => {
const access_token = req.session.access_token;
const balanceResponse = await client.accountsBalanceGet({
access_token,
});
res.json(balanceResponse.data);
});
app.get("/api/identity", async (req, res, next) => {
const access_token = req.session.access_token;
const identityResponse = await client.identityGet({
access_token,
});
response.json({ identity: identityResponse.data.accounts });
});
function errorLogger(error, req, res, next) {
// for logging errors
console.error(error); // or using any fancy logging library
next(error); // forward to next middleware
}
function errorResponder(error, req, res, next) {
// responding to client
console.log(Object.keys(error));
if (error.response.status && error.response.data.error_message) {
res.status(error.response.status).send(
`${error.response.status} Error`
);
}
// res.status(404).send(error)
// if (error.type == 'redirect')
// res.redirect('/error')
// else if (error.type == 'time-out') // arbitrary condition check
// res.status(408).send(error)
else next(error); // forwarding exceptional case to fail-safe middleware
}
function failSafeHandler(error, req, res, next) {
// generic handler
res.status(500).send(error);
}
app.use(errorLogger);
app.use(errorResponder);
app.use(failSafeHandler);
app.listen(process.env.PORT || 8080);