This is the code that runs https://bandolier.learnjsthehardway.com/ for you to review. It uses the https://git.learnjsthehardway.com/learn-javascript-the-hard-way/bandolier-template to create the documentation for the project.
https://bandolier.learnjsthehardway.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
7.7 KiB
172 lines
7.7 KiB
/*
|
|
This is mostly a convenience that translates the `secrets/config.json` file into
|
|
easily accessible imports for the code. This file should be safe to commit to
|
|
git, but __do not__ commit `secrets/config.json` to git. At the same time, do not
|
|
put secrets directly in here. Instead, put them in `secrets/config.json` then
|
|
convert it to a variable here.
|
|
|
|
The primary purpose of this file is to make it easier to safely import configurations,
|
|
and to document what those configurations should be. You can't put documentation on
|
|
a `config.json` file but you can put it in `config.js`, so that's what I did.
|
|
|
|
The live configuration is in `secrets/config.json`, and that file is created from the
|
|
templates in `commands/templates/secrets/config.json`.
|
|
*/
|
|
import assert from "assert";
|
|
import fs from "fs";
|
|
|
|
/*
|
|
The path to the secret config.json file.
|
|
*/
|
|
export const CONFIG = "./secrets/config.json"
|
|
|
|
const load_config = () => {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(CONFIG));
|
|
} catch(error) {
|
|
console.error(error, `You have a problem with your ${CONFIG}.`);
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/*
|
|
All of the secrets directly available. You can just impor this and
|
|
access what you want instead of using the variables below. Very helpful
|
|
if you just added something to the `secrets/config.json` but haven't
|
|
modified this file yet.
|
|
*/
|
|
export const secrets = load_config();
|
|
assert(secrets !== undefined, `Problem loading config file ${CONFIG}`);
|
|
|
|
/*
|
|
The paypal configuration used in `api/payments/paypal.js` and `client/components/Paypal.svelte`.
|
|
The configuration is an object with:
|
|
|
|
+ `"email"`: `string` of your Paypal email. ___NOT PUBLIC___
|
|
+ `"client_id"`: `string` of your Paypal ___PUBLIC___ client id. This is exposed to the user, but ___NOT__ the `secret`.
|
|
+ `"secret"`: `string` of your Paypal __PRIVATE__ id. __NEVER__ put the in a page in `client`.
|
|
+ `"disabled"`: `boolean` to indicate if this is disabled or not.
|
|
|
|
___FOOTGUN___: You will have a very bad time if the `"secret"` key is placed
|
|
in any page that's accessible on the internet. With that someone else can
|
|
drain your account, do charges, and many other things. Consider creating a
|
|
restricted API key if you can instead of a full service one, to reduce your
|
|
risk.
|
|
*/
|
|
export const paypal_private = secrets.paypal_private;
|
|
|
|
/*
|
|
Your BTCPayServer configuration. This uses the BTCPayServer "greenfield" API, which is
|
|
easier to use than the old one. This is used by `api/payments/btcpay.js` and `client/components/BTCPay.svelte`.
|
|
|
|
+ `"url"`: `string` of your store's URL, something like `"https://btctest.learnjsthehardway.com/api/v1/stores/HEXSTRING"`.
|
|
+ `"auth"`: `string` Your basic auth credentials of the form "Basic BASE64HEX=". ___NOT PUBLIC___.
|
|
+ `"disabled"`: `boolean` If this is disabled or not.
|
|
|
|
___FOOTGUN___: Do not put the `"auth"` on the internet as it should be private and only used by the `api/payments/btcpay.js`.
|
|
*/
|
|
export const btcpay_private = secrets.btcpay_private;
|
|
|
|
/*
|
|
Stripe configuration used by `api/payments/stripe.js`, `api/payments/stripe_webhook.js` and `client/components/Stripe.svelte`.
|
|
|
|
|
|
+ '"email"': `string` Your Stripe email. __NOT PUBLIC__? I'm not sure about this.
|
|
+ '"client_id"': `string` Your Stripe public key. __PUBLIC__ and given to the browser.
|
|
+ '"secret"': `string` Your Stripe ___SECRET__ key. __NOT PUBLIC__. Do not expose this.
|
|
+ '"endpoint_secret"': `string` Shared secret with Stripe and used in `api/payments/stripe_webhook.js` to validate Stripe's webhook callbacks. __NOT PUBLIC__
|
|
+ '"api_version"': `string` The version of the API that should be used. Currently "2022-08-01".
|
|
+ '"disabled"': `boolean` Whether Stripe is disabled or not.
|
|
|
|
___FOOTGUN___: Do not expose the `endpoint_secret`, `secret`, or `email` to the internet.
|
|
*/
|
|
export const stripe_private = secrets.stripe_private;
|
|
|
|
/*
|
|
Used in redirects and some links. Should be the __entire__ base URL, including ports and
|
|
protocols __without__ a trailing slash. For example:
|
|
|
|
+ "base_host": "http://127.0.0.1:5001"
|
|
+ "base_host": "https://learnjsthehardway.com"
|
|
*/
|
|
export const base_host = secrets.base_host;
|
|
|
|
/*
|
|
Configuration for the bull queue. It should just be the configuration for your
|
|
Redis server, which is usually this:
|
|
|
|
```javascript
|
|
"bull_config": {
|
|
"redis": {
|
|
"host": "localhost",
|
|
"port": 6379,
|
|
"db": 5
|
|
}
|
|
},
|
|
```
|
|
|
|
Refer to the [Bull Documentation](https://github.com/OptimalBits/bull) for more.
|
|
*/
|
|
export const bull_config = secrets.bull_config;
|
|
|
|
/*
|
|
A `string` of either "redis" or "memory" for either a RedisStore, or
|
|
MemoryStore in Passport.js. Used in `lib/auth.js`.
|
|
*/
|
|
export const session_store = secrets.session_store;
|
|
|
|
/*
|
|
Used by the `commands/media.js` loader to process media files and configure the .torrent file generation. It's _kind_ of specific to my setup but study the `commands/media.js` file for what I do.
|
|
|
|
+ `"root_db"`: This is my private source database, which is a directory of `.md` and `.js` files I use to build my content.
|
|
+ `"tracker"`: Currently the Tracker WebSocket URL. For dev that's `"ws://localhost:9001"`, and in production it's `wss://learnjsthehardway.com/tracker` so you get SSL WebSockets.
|
|
*/
|
|
export const loader = secrets.loader;
|
|
|
|
/*
|
|
This configures the cookies in the `commands/api.js` for the web browser's cookies.
|
|
|
|
+ `"cookie_domain"`: "127.0.0.1" for development, the __exact__ protocol://host:port for your cookies.
|
|
+ `"cookie_secret"`: "changeme" for development but ___CHANGE THIS NOW___.
|
|
|
|
___FOOTGUN___: Cookies are so messed up that it's hard to debug why they fail. If you find that you can't log in to the server, or that your login disappears after you refresh then:
|
|
|
|
1. Make sure you aren't using MemoryStore configuration using `secrets.auth = "memory"`. This will make it forget your login if the server restarts, which you might think is from browser refresh.
|
|
2. Add `--cookies-suck` to `node bando.js api` so it will dump what it thinks your cookies are and what they should be.
|
|
3. Look at the Inspector window in your browser for the Network tab and see what it's sending as the cookie, if any.
|
|
|
|
The best advice is that this setting must be exactly the same as what the browser sees. Protocol, port, hostname, everthing must be the same.
|
|
*/
|
|
export const auth = secrets.auth;
|
|
|
|
/*
|
|
During deployment I do a simple `rsync` of media to additional media servers. This makes a
|
|
simple dirt cheap CDN when combined with WebTorrent. These will be added to the `.torrent`
|
|
files for each media in `commands/media.js` so that the browser will pull content from all
|
|
servers at the same time.
|
|
|
|
+ `["string", "string"]` -- A list of full URLs to each media server, as they should be in the `.torrent`.
|
|
*/
|
|
export const media_servers = secrets.media_servers;
|
|
|
|
/*
|
|
The `queues/discord.js` and `api/discord.js` provide a very simple Discord integration where
|
|
people can request a key after agreeing to a Code of Conduct, then join a discord. It's
|
|
_VERY_ simple, so look in the code to see how it works.
|
|
|
|
+ `"token"`: `string` Your discord key. __PRIVATE__
|
|
+ `"time_limit"`: `"24 hours"` Verbal description of the time limit, used in emails and pages for the user to know how long they have to claim an invite.
|
|
+ `"invites"`: `{ "maxAge": 86400, "maxUses": 1, "unique": true}` How the invites work. I suggest these options so you can map one invite to one user.
|
|
*/
|
|
export const discord = secrets.discord;
|
|
|
|
/*
|
|
Used by some services when talking to `socket/` handlers for events.
|
|
It's mostly a security mechanism to make sure only our code is sending certain
|
|
events and should be a giant cryptographically random key.
|
|
|
|
+ `"api_key"`: "AHEXCODE" make it big and truly random.
|
|
*/
|
|
export const socket = secrets.socket;
|
|
|
|
export default secrets;
|
|
|