Created
May 15, 2024 15:36
-
-
Save fabriziogiordano/9a56f2b2ebbbc4ec0c313ff164fc6fa1 to your computer and use it in GitHub Desktop.
Schwab - token flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ps aux | grep "ssh -L"|grep -v grep|awk '{print $2}'|xargs kill | |
ssh -L 443:127.0.0.1:443 -N -f root@linode; echo "linode: 443" | |
*/ | |
import dotenv from "dotenv"; | |
dotenv.config({ path: `${process.env.GAP_FOLDER}/.env` }); | |
import fs from "fs"; | |
import got from "got"; | |
import { db } from "../db/index.js"; | |
import Fastify from "fastify"; | |
//SSL cert | |
const fastify = Fastify({ | |
logger: false, | |
https: { | |
key: fs.readFileSync("./certs/key.pem"), | |
cert: fs.readFileSync("./certs/certificate.pem"), | |
}, | |
}); | |
const port = 443; | |
const host = "0.0.0.0"; | |
const tokenJson = `${process.env.GAP_FOLDER}/utils/token/token.json`; | |
const { SCHWAB_APIKEY, SCHWAB_SECRET, SCHWAB_CALLBACK_URI } = process.env; | |
const BASIC = btoa(`${SCHWAB_APIKEY}:${SCHWAB_SECRET}`); | |
console.log("URL"); | |
console.log(`https://api.schwabapi.com/v1/oauth/authorize?client_id=${SCHWAB_APIKEY}&redirect_uri=${encodeURIComponent(SCHWAB_CALLBACK_URI)}`); | |
fastify.get("/callback", async (req, res) => { | |
console.log("Waiting for the token"); | |
try { | |
const options = { | |
// See the Authentication API's Post Access Token method for more information | |
url: "https://api.schwabapi.com/v1/oauth/token", | |
method: "POST", | |
headers: { | |
Authorization: `Basic ${BASIC}`, | |
"Content-Type": "application/x-www-form-urlencoded", | |
}, | |
// POST Body params | |
form: { | |
grant_type: "authorization_code", | |
access_type: "offline", | |
code: req.query.code, //get the code | |
redirect_uri: SCHWAB_CALLBACK_URI, | |
}, | |
}; | |
console.log("Sending request to verify token"); | |
const response = await got(options); | |
// Post Access Token request | |
if (response.statusCode === 200) { | |
console.log("Token verified"); | |
const authReply = JSON.parse(response.body); | |
try { | |
const tokenText = JSON.stringify(authReply, null, " "); | |
fs.writeFileSync(tokenJson, tokenText); | |
console.log("Token file updated"); | |
// Do not save on the DB Yet | |
await saveToken(tokenText); | |
await res.send(authReply); | |
await fastify.close(); | |
console.log("Successfully closed!"); | |
process.exit(200); | |
} catch (error) { | |
console.error(error); | |
} | |
} else { | |
console.error(response.statusCode); | |
} | |
} catch (error) { | |
console.error(error); | |
} | |
}); | |
fastify.get("/refresh", async (req, res) => { | |
try { | |
console.log("Refreshing"); | |
const { refresh_token } = JSON.parse(fs.readFileSync(tokenJson, "utf-8")); | |
const response = await got({ | |
// See the Authentication API's Post Access Token method for more information | |
url: "https://api.schwabapi.com/v1/oauth/token", | |
method: "POST", | |
headers: { | |
Authorization: `Basic ${BASIC}`, | |
"Content-Type": "application/x-www-form-urlencoded", | |
}, | |
// POST Body params | |
form: { | |
grant_type: "refresh_token", | |
refresh_token: refresh_token, | |
}, | |
}); | |
// Post Access Token request | |
if (response.statusCode === 200) { | |
// See Post Access Token response summary for what authReply contains | |
const authReply = JSON.parse(response.body); | |
fs.writeFileSync(tokenJson, JSON.stringify(authReply, null, " ")); | |
console.log("Token updated"); | |
await res.send(authReply); | |
} else { | |
await res.send(response.statusCode); | |
} | |
} catch (error) { | |
console.error(error); | |
await res.send(error); | |
} | |
}); | |
// Run the server! | |
const start = async () => { | |
try { | |
console.log("Here"); | |
await fastify.listen({ port: port, host: host }); | |
console.log("Token server started"); | |
} catch (error) { | |
fastify.log.error(error); | |
console.error(error); | |
process.exit(1); | |
} | |
}; | |
start(); | |
// Save token in DB | |
async function saveToken(tokenText) { | |
try { | |
const now = new Date().getTime(); | |
const clearRegularTokens = "DELETE FROM tokens WHERE type = 'regular' AND platform = 'schwab'"; | |
const setTokenQueryParams = [now, tokenText]; | |
const setTokenQueryText = ` | |
INSERT INTO tokens (datetime, type, value, platform) | |
VALUES ($1, 'regular', $2, 'schwab'); | |
`; | |
console.log(clearRegularTokens); | |
console.log(setTokenQueryParams); | |
await db.query(clearRegularTokens); | |
await db.query(setTokenQueryText, setTokenQueryParams); | |
await db.end(); | |
} catch (error) { | |
console.error("Token NOT updated in DB"); | |
console.error(error.stack); | |
} | |
console.log("Token updated in DB"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment