[READ-ONLY] Mirror of https://github.com/probablykasper/cryp. Cryptocurrency portfolio tracker (unfinished)
0

Configure Feed

Select the types of activity you want to include in your feed.

Added TLS! Updated READMES

KH (Jan 29, 2018, 5:34 PM +0100) 95f2eabd 25070411

+94 -398
+9
.env
··· 1 + CRYP_ENV=dev 2 + 3 + CERT_DOMAIN=2.kasp.io 4 + CERT_EMAIL=kasperkh.kh@gmail.com 5 + 6 + PORT_INSECURE=80 7 + PORT_SECURE=443 8 + PORT_DB=27017 9 + PORT_MONGO_EXPRESS=8081
-2
.gitattributes
··· 1 - # Auto detect text files and perform LF normalization 2 - * text=auto
+1 -1
.gitignore
··· 1 - ferrum 1 + web/letsencrypt 2 2 **/keys.js 3 3 db/db
+14 -10
README.md
··· 1 - # vidl-web 1 + # Cryp 2 2 Cryptocurrency portfolio tracker 3 3 4 - # ToDo 5 - - Empty 6 - 7 - # Get started 8 - - **CRYP_ENV** environment variable in docker-compose.yml 9 - - Dev: **dev** 10 - - Production: **production** 11 - - Fill in your Google API Client ID and Client Secret in web/src/modules/keys.js. To get that: 4 + ### Get Started 5 + - Install Docker Compose if you do not already have it. 6 + - Set your environment variables in `environment.env`. This assumes your server only uses *one* domain. 7 + - `CRYP_ENV`: `dev` or `production`. 8 + - `CERT_DOMAIN`: Set this to your domain name. 9 + - `CERT_EMAIL`: The email your TLS certficiate will be registered with. 10 + - Create the file `web/node/keys.js`, and fill in your Google API Client ID and Client Secret in it. To get those: 12 11 1. Go to the [APIs section of GCP](https://console.cloud.google.com/apis/credentials) and create a project, then select it. 13 12 2. Click "Create credentials" and "OAuth client ID". 14 - 3. The Application type should be Web application. Now add your Authorized redirect URIs. Add "http://localhost/auth/google/callback" for local development and add another one for production, replacing "localhost" with your own domain name. 13 + 3. The Application type should be Web application. Now add your Authorized redirect URIs. Add `http://localhost/auth/google/callback` for local development and add another one for production, replacing `localhost` with your own domain name and `http` with `https`. 15 14 4. Press "Create", and you'll be presented with your client ID and secret. 16 15 17 16 Your keys.js file should have this format: ··· 23 22 } 24 23 } 25 24 ``` 25 + 26 + ### Usage 27 + - Register TLS certificate: `docker-compose up letsencrypt-init`. 28 + - Renew TLS certificate: `docker-compose up letsencrypt-renew`. 29 + - Start server: `docker-compose up web mongo-express`. Exclude `mongo-express` in production.
+32 -29
docker-compose.yml
··· 1 1 version: "3.3" 2 2 services: 3 3 web: 4 - build: ./web 5 - container_name: web 4 + build: 5 + context: ./web 6 + dockerfile: web.Dockerfile 7 + env_file: 8 + - .env 6 9 ports: 7 - - 80:80 8 - - 443:443 10 + - ${PORT_INSECURE}:${PORT_INSECURE} 11 + - ${PORT_SECURE}:${PORT_SECURE} 12 + links: 13 + - db 14 + depends_on: 15 + - db 9 16 volumes: 10 17 - ./web:/usr/src/app 11 - links: 12 - - db 13 - environment: 14 - - "CRYP_ENV=dev" 15 - - "CRYP_INSECURE_PORT=80" 16 - - "CRYP_SECURE_PORT=443" 17 18 18 19 mongo-express: 19 20 image: mongo-express:0.42 20 21 ports: 21 - - 8081:8081 22 + - ${PORT_MONGO_EXPRESS}:${PORT_MONGO_EXPRESS} 22 23 links: 23 24 - db 24 25 environment: ··· 35 36 - ./db/db:/data/db 36 37 restart: always 37 38 38 - zerossl: 39 - image: zerossl/client:latest 40 - depends_on: 41 - - web 42 - # command: -help 43 - command: -domains "cryp.kasp.io" -email "kh@kasp.io" -unlink -generate-missing -path /webroot -renew 30 -key account.key -crt domain.crt -csr domain.csr -csr-key domain.key 44 - # -live production 45 - # -unlink remove challenge files automatically 46 - # -generate-missing generate missing files (key, csr, csr-key) 47 - # -email 48 - # -path path to .well-known/acme-challenge/ 49 - # -renew <days> renew if less than x days till expiration 50 - 39 + letsencrypt-init: 40 + image: certbot/certbot:v0.21.1 41 + env_file: 42 + - .env 43 + ports: 44 + - 80:80 45 + - 443:443 46 + volumes: 47 + - ./web/letsencrypt/etc/letsencrypt:/etc/letsencrypt 48 + - ./web/letsencrypt/var/lib/letsencrypt:/var/lib/letsencrypt 49 + - ./web/letsencrypt/usr/share/nginx/html:/usr/share/nginx/html 50 + command: certonly -n -d ${CERT_DOMAIN} -m ${CERT_EMAIL} --standalone --agree-tos 51 + letsencrypt-renew: 52 + image: certbot/certbot:v0.21.1 53 + env_file: 54 + - .env 51 55 volumes: 52 - - ./web/src/tls:/data 53 - - ./web/src/static/.well-known/acme-challenge:/webroot 54 - 55 - 56 - # docker run --rm -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh 56 + - ./web/letsencrypt/etc/letsencrypt:/etc/letsencrypt 57 + - ./web/letsencrypt/var/lib/letsencrypt:/var/lib/letsencrypt 58 + - ./web/letsencrypt/usr/share/nginx/html:/usr/share/nginx/html 59 + command: certonly -n -d 2.kasp.io --webroot -w /usr/share/nginx/html --agree-tos
+1 -1
web/Dockerfile web/web.Dockerfile
··· 12 12 13 13 COPY . . 14 14 15 - CMD npm run $CRYP_ENV 15 + CMD npm ${CRYP_ENV}
+2 -2
web/nodemon.json
··· 1 1 { 2 2 "watch": [ 3 - "src/server.js", 4 - "src/node" 3 + "server.js", 4 + "node" 5 5 ], 6 6 "ext": "js" 7 7 }
+2 -2
web/package.json
··· 7 7 8 8 "scripts": { 9 9 "build-dev": "webpack --config webpack.config.js --watch", 10 - "start-dev": "nodemon src/server.js", 10 + "start-dev": "nodemon server.js", 11 11 "dev": "npm-run-all --parallel build-dev start-dev", 12 12 13 13 "build-production": "webpack --config webpack.config.js", 14 - "start-production": "node src/server.js", 14 + "start-production": "node server.js", 15 15 "production": "npm-run-all build-production start-production" 16 16 }, 17 17 "dependencies": {
web/src/js/big.js web/js/big.js
web/src/js/calculate.js web/js/calculate.js
web/src/js/global.js web/js/global.js
web/src/js/old_global.js web/js/old_global.js
web/src/node/get-certs.js web/node/get-certs.js
web/src/node/https-redirect-server.js web/node/https-redirect-server.js
web/src/node/mongoose-models.js web/node/mongoose-models.js
web/src/node/passport-setup.js web/node/passport-setup.js
web/src/node/passport.js web/node/passport.js
+5 -1
web/src/node/routes.js web/node/routes.js
··· 1 1 "use strict"; 2 2 const passport = require("passport"); 3 - const logErr = require("./common").logErr; 3 + const logErr = (err) => { 4 + console.log("---------- error code "+code); 5 + console.log(err); 6 + console.log("----------"); 7 + }; 4 8 const scope = {scope: ["profile"]}; 5 9 const User = require("./mongoose-models").User; 6 10
web/src/node/temp-server.js web/node/temp-server.js
web/src/pug/logged-in/balance.pug web/pug/logged-in/balance.pug
web/src/pug/logged-in/gains.pug web/pug/logged-in/gains.pug
web/src/pug/logged-in/overview.pug web/pug/logged-in/overview.pug
web/src/pug/logged-in/transactions.pug web/pug/logged-in/transactions.pug
web/src/pug/logged-out/404.pug web/pug/logged-out/404.pug
web/src/pug/logged-out/home.pug web/pug/logged-out/home.pug
web/src/pug/template.pug web/pug/template.pug
-73
web/src/sass.js
··· 1 - /******/ (function(modules) { // webpackBootstrap 2 - /******/ // The module cache 3 - /******/ var installedModules = {}; 4 - /******/ 5 - /******/ // The require function 6 - /******/ function __webpack_require__(moduleId) { 7 - /******/ 8 - /******/ // Check if module is in cache 9 - /******/ if(installedModules[moduleId]) { 10 - /******/ return installedModules[moduleId].exports; 11 - /******/ } 12 - /******/ // Create a new module (and put it into the cache) 13 - /******/ var module = installedModules[moduleId] = { 14 - /******/ i: moduleId, 15 - /******/ l: false, 16 - /******/ exports: {} 17 - /******/ }; 18 - /******/ 19 - /******/ // Execute the module function 20 - /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 - /******/ 22 - /******/ // Flag the module as loaded 23 - /******/ module.l = true; 24 - /******/ 25 - /******/ // Return the exports of the module 26 - /******/ return module.exports; 27 - /******/ } 28 - /******/ 29 - /******/ 30 - /******/ // expose the modules object (__webpack_modules__) 31 - /******/ __webpack_require__.m = modules; 32 - /******/ 33 - /******/ // expose the module cache 34 - /******/ __webpack_require__.c = installedModules; 35 - /******/ 36 - /******/ // define getter function for harmony exports 37 - /******/ __webpack_require__.d = function(exports, name, getter) { 38 - /******/ if(!__webpack_require__.o(exports, name)) { 39 - /******/ Object.defineProperty(exports, name, { 40 - /******/ configurable: false, 41 - /******/ enumerable: true, 42 - /******/ get: getter 43 - /******/ }); 44 - /******/ } 45 - /******/ }; 46 - /******/ 47 - /******/ // getDefaultExport function for compatibility with non-harmony modules 48 - /******/ __webpack_require__.n = function(module) { 49 - /******/ var getter = module && module.__esModule ? 50 - /******/ function getDefault() { return module['default']; } : 51 - /******/ function getModuleExports() { return module; }; 52 - /******/ __webpack_require__.d(getter, 'a', getter); 53 - /******/ return getter; 54 - /******/ }; 55 - /******/ 56 - /******/ // Object.prototype.hasOwnProperty.call 57 - /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58 - /******/ 59 - /******/ // __webpack_public_path__ 60 - /******/ __webpack_require__.p = ""; 61 - /******/ 62 - /******/ // Load entry module and return exports 63 - /******/ return __webpack_require__(__webpack_require__.s = 0); 64 - /******/ }) 65 - /************************************************************************/ 66 - /******/ ([ 67 - /* 0 */ 68 - /***/ (function(module, exports) { 69 - 70 - // removed by extract-text-webpack-plugin 71 - 72 - /***/ }) 73 - /******/ ]);
web/src/sass/buttons.sass web/sass/buttons.sass
web/src/sass/cards.sass web/sass/cards.sass
web/src/sass/defaults.sass web/sass/defaults.sass
web/src/sass/global.sass web/sass/global.sass
web/src/sass/template.sass web/sass/template.sass
web/src/sass/variables.sass web/sass/variables.sass
+28 -31
web/src/server.js web/server.js
··· 1 1 "use strict"; 2 - // native modules 3 - const path = require("path"); 4 - // dir function 2 + const express = require("express"); 3 + const http = require("http"); 4 + const https = require("https"); 5 + const fs = require("fs"); 5 6 global.dir = (dirPath) => { 6 7 return require("path").resolve(__dirname, dirPath); 7 8 } 8 9 9 - // config 10 - const keyPath = dir("tls/domain.key"); 11 - const certPath = dir("tls/domain.crt"); 12 - const insecurePort = process.env.CRYP_INSECURE_PORT; 13 - const securePort = process.env.CRYP_SECURE_PORT; 10 + const PORT_INSECURE = process.env.PORT_INSECURE; 11 + const PORT_SECURE = process.env.PORT_SECURE; 14 12 15 - const tempServer = require("./node/temp-server"); 16 - tempServer.start(insecurePort); 13 + // http 14 + (() => { 15 + const httpApp = express(); 16 + httpApp.get("/", function (req, res) { 17 + console.log("user http"); 18 + res.send("You found the HTTP server"); 19 + }); 20 + http.createServer(httpApp).listen(80, () => { 21 + console.log("httpApp listening on port "+80); 22 + }); 23 + })(); 17 24 18 - const getCerts = require("./node/get-certs"); 19 - getCerts(keyPath, certPath, () => { 25 + // https 26 + (() => { 20 27 21 - tempServer.close(); 22 - 23 - // httpsRedirectServer 24 - const httpsRedirectServer = require("./node/https-redirect-server"); 25 - httpsRedirectServer.start(insecurePort, securePort); 26 - 27 - 28 - 29 - const express = require("express"); 28 + // https 30 29 const app = express(); 31 30 32 31 // load view engine 33 - // app.set("views", require("path").resolve(__dirname, "pug")); 34 32 app.set("views", dir("pug")); 35 33 app.set("view engine", "pug"); 36 34 ··· 38 36 app.use("/", express.static(dir("static"), { redirect: false })); 39 37 app.use("/", express.static(dir("static/favicon"), { redirect: false })); 40 38 39 + const bodyParser = require("body-parser"); 41 40 // parse application/x-www-form-urlencoded 42 41 app.use(bodyParser.urlencoded({ extended: false })); 43 42 // parse application/json 44 43 app.use(bodyParser.json({ type: "application/json" })); 45 44 46 - // start server 47 - httpsOptions = { 48 - key: fs.readFileSync(keyPath), 49 - cert: fs.readFileSync(certPath) 50 - }; 51 - 52 45 // mongoose 53 46 const mongoose = require("mongoose"); 54 47 mongoose.connect("mongodb://db/cryp"); ··· 81 74 // routes 82 75 require("./node/routes")(app); 83 76 84 - https.createServer(httpsOptions, app).listen(securePort, () => { 85 - console.log("https server started"); 77 + const httpsOptions = { 78 + key: fs.readFileSync(dir(`letsencrypt/etc/letsencrypt/live/${process.env.CERT_DOMAIN}/privkey.pem`)), 79 + cert: fs.readFileSync(dir(`letsencrypt/etc/letsencrypt/live/${process.env.CERT_DOMAIN}/cert.pem`)) 80 + }; 81 + https.createServer(httpsOptions, app).listen(443, () => { 82 + console.log("app listening on port "+443); 86 83 }); 87 84 88 - }); 85 + })();
-62
web/src/serverold.js
··· 1 - "use strict"; 2 - // modules 3 - const bodyParser = require("body-parser"); 4 - // express 5 - const express = require("express"); 6 - const app = express(); 7 - // dir function 8 - const path = require("path"); 9 - global.dir = (dirPath) => { 10 - return require("path").resolve(__dirname, dirPath); 11 - } 12 - 13 - // load view engine 14 - // app.set("views", require("path").resolve(__dirname, "pug")); 15 - app.set("views", dir("pug")); 16 - app.set("view engine", "pug"); 17 - 18 - // static content 19 - app.use("/", express.static(dir("static"), { redirect: false })); 20 - app.use("/", express.static(dir("static/favicon"), { redirect: false })); 21 - 22 - // parse application/x-www-form-urlencoded 23 - app.use(bodyParser.urlencoded({ extended: false })); 24 - // parse application/json 25 - app.use(bodyParser.json({ type: "application/json" })); 26 - 27 - // mongoose 28 - const mongoose = require("mongoose"); 29 - mongoose.connect("mongodb://db/cryp"); 30 - const db = mongoose.connection; 31 - const dbSuc = "\x1b[42m[Mongoose]\x1b[0m "; 32 - db.on("error", console.error.bind(console, "connection error:")); 33 - db.once("open", () => { 34 - console.log(dbSuc+"connected to MongoDB"); 35 - }); 36 - 37 - // passport 38 - const passport = require("passport"); 39 - const passportSetup = require("./node/passport-setup"); 40 - const session = require("express-session"); 41 - const MongoStore = require("connect-mongo")(session); 42 - app.use(session({ 43 - // key: "sess", 44 - secret: "tomatonanaboy69:o", 45 - store: new MongoStore({ 46 - mongooseConnection: mongoose.connection, 47 - ttl: 60*60*24*90, 48 - touchAfter: 60*60*24 49 - }), 50 - resave: false, 51 - saveUninitialized: false 52 - })); 53 - app.use(passport.initialize()); 54 - app.use(passport.session()); 55 - 56 - // routes 57 - require("./node/routes")(app); 58 - 59 - // start server 60 - const server = app.listen(80, () => { 61 - console.log("Express server listening on 80"); 62 - });
web/src/static/Chart.bundle.min.js web/static/Chart.bundle.min.js
web/src/static/big.min.js web/static/big.min.js
web/src/static/global.css web/static/global.css
web/src/static/global.js web/static/global.js
web/src/static/global.sass web/static/global.sass
web/src/static/icons/logout.svg web/static/icons/logout.svg
web/src/static/icons/signout.svg web/static/icons/signout.svg
-51
web/src/tls/account.key
··· 1 - -----BEGIN RSA PRIVATE KEY----- 2 - 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 51 - -----END RSA PRIVATE KEY-----
-53
web/src/tls/domain.crt
··· 1 - -----BEGIN CERTIFICATE----- 2 - MIIF3DCCBMSgAwIBAgITAPot6r160oM8OBT1freylx5/nTANBgkqhkiG9w0BAQsFADAiMSAwHgYD 3 - VQQDDBdGYWtlIExFIEludGVybWVkaWF0ZSBYMTAeFw0xODAxMTgyMDUzMDRaFw0xODA0MTgyMDUz 4 - MDRaMBcxFTATBgNVBAMTDGNyeXAua2FzcC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC 5 - ggIBAPzqtc8NGnna29ZqP0wieK++dZ38V+cmDyFu9k5dAZTQ1CU6hIIQLVmDjK/aVuwk66wPLC7a 6 - 68vebuC3gVgolug/P58JtAMf6yA5ha9ssopHzx7vMCZg7mcVWzVOo0KeDFyvNG6W4MwUO2wPLTLe 7 - 23h2WpUo98DShS5G3szfyH+7SdI2npFhfl8UBjk2mu5M16rzV75MjbQTWoVVuZhLqxzQqkPqJu/s 8 - mLouU/HUbBPdaK9mooSp4zOoTVDNKoTu6vYg1i28AyZEPiKx5EkZdcxEAoBxTAiGTiIsBl8grBa0 9 - 6WAQ+DkTRSOPRmdKRoqAT4X/udwHItxtOUs4e4a2hqrOgAVmUa6rLAaAhlr+N51lnpVHoCeATf2s 10 - wFzC0qMgyCnkQQ0JOBH3WVBM1wpYc4pR1qihGWUphumoPl9TudGUGLx6/GoahNhB8IQF2k/1s21R 11 - gkh8OkniznQImuOCn8JgpobKNV+EO5nBiUsbenn6u0totYTgY9/hHbNEqB1jejVAy/9NcYA9dJ12 12 - HWXlp6+O+jVS5YKGDz1Mzh6JLD9I1Bikxs90GrhtfSGkeKS/+UhV4Yi9UNWAIvCOAGZQWUY5dC5U 13 - zRhq9TXow0Iqvy5cUKQq2b8WL/mAOeD2X3CGMIRoxcutKtjeksEaf3T2cFyJ3dEbNlc/xEoAdUo9 14 - 16ITAgMBAAGjggIUMIICEDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG 15 - AQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFHb+rVRCJINvjjWD4FDjvBbVGTQPMB8GA1Ud 16 - IwQYMBaAFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHcGCCsGAQUFBwEBBGswaTAyBggrBgEFBQcwAYYm 17 - aHR0cDovL29jc3Auc3RnLWludC14MS5sZXRzZW5jcnlwdC5vcmcwMwYIKwYBBQUHMAKGJ2h0dHA6 18 - Ly9jZXJ0LnN0Zy1pbnQteDEubGV0c2VuY3J5cHQub3JnLzAXBgNVHREEEDAOggxjcnlwLmthc3Au 19 - aW8wgf4GA1UdIASB9jCB8zAIBgZngQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIB 20 - FhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENlcnRp 21 - ZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFydGllcyBhbmQgb25s 22 - eSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRw 23 - czovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEACdjBPg5K 24 - qeKZxTKUW/mG2Hb7rnvTxLazdcvzpFCVHua/DmYaFbj/nRDP62qTvXMY4j+gx8cL+2Udhjsx4j9q 25 - YZHBEE9UtOkng6lR+hbrI9jDBXdOM6pWsC3R+eyt/7p4GTe5vxLw9V5GqByiOrx4gsahXCgJJ4nc 26 - fMkIWrG7GovWJ/Rq4cnOIzV9cJjI8WkmLZ5R+r/c3OcKBFFm8QKCPlncref1NetaLcL1erDv5JAn 27 - DIbDUkyIoUhbrtIypVKXqWvkK5SUyOIeo6H9JQi8RPU1/4EX6uVTLRaAxne9+4uICrEjxGwgHVWV 28 - D6auaopuBwBmt81HHxtDOimAQv2wnw== 29 - -----END CERTIFICATE----- 30 - -----BEGIN CERTIFICATE----- 31 - MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UE 32 - AwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2MDUyMzIyMDc1OVowIjEgMB4G 33 - A1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 34 - AoIBAQDtWKySDn7rWZc5ggjz3ZB08jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbX 35 - F5/yt8aWPpUKnPymoLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7Axm 36 - S1m0ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCNxDH1Hizq 37 - +GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56dhMfzCgOKXeJ340WhW3T 38 - jD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQD 39 - AgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoG 40 - CCsGAQUFBwEBBG4wbDA0BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2Vu 41 - Y3J5cHQub3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2VuY3J5 42 - cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkqhkiG9w0BAQsFAAOC 43 - AgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjFUGeVOv3NnLyfofuUOjEbY5irFCDt 44 - nv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2 45 - rtGtazSqVqK9E07sGHMCf+zpDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBF 46 - RFclzLRjo/h7IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf 47 - zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCIPTAvjV+4ni78 48 - 6iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2wSVuvdDM5zGv2f9ltNWUiYZHJ 49 - 1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7v 50 - O0+NTXlgrRofRT6pVywzxVo6dND0WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdo 51 - dMB3RIwt7RFQ0uytn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNo 52 - AxU= 53 - -----END CERTIFICATE-----
-28
web/src/tls/domain.csr
··· 1 - -----BEGIN CERTIFICATE REQUEST----- 2 - MIIEtzCCAp8CAQAwSDEKMAgGA1UEBwwBLTEVMBMGA1UEAwwMY3J5cC5rYXNwLmlv 3 - MQowCAYDVQQIDAEtMQowCAYDVQQKDAEtMQswCQYDVQQGEwJHQjCCAiIwDQYJKoZI 4 - hvcNAQEBBQADggIPADCCAgoCggIBAPzqtc8NGnna29ZqP0wieK++dZ38V+cmDyFu 5 - 9k5dAZTQ1CU6hIIQLVmDjK/aVuwk66wPLC7a68vebuC3gVgolug/P58JtAMf6yA5 6 - ha9ssopHzx7vMCZg7mcVWzVOo0KeDFyvNG6W4MwUO2wPLTLe23h2WpUo98DShS5G 7 - 3szfyH+7SdI2npFhfl8UBjk2mu5M16rzV75MjbQTWoVVuZhLqxzQqkPqJu/smLou 8 - U/HUbBPdaK9mooSp4zOoTVDNKoTu6vYg1i28AyZEPiKx5EkZdcxEAoBxTAiGTiIs 9 - Bl8grBa06WAQ+DkTRSOPRmdKRoqAT4X/udwHItxtOUs4e4a2hqrOgAVmUa6rLAaA 10 - hlr+N51lnpVHoCeATf2swFzC0qMgyCnkQQ0JOBH3WVBM1wpYc4pR1qihGWUphumo 11 - Pl9TudGUGLx6/GoahNhB8IQF2k/1s21Rgkh8OkniznQImuOCn8JgpobKNV+EO5nB 12 - iUsbenn6u0totYTgY9/hHbNEqB1jejVAy/9NcYA9dJ12HWXlp6+O+jVS5YKGDz1M 13 - zh6JLD9I1Bikxs90GrhtfSGkeKS/+UhV4Yi9UNWAIvCOAGZQWUY5dC5UzRhq9TXo 14 - w0Iqvy5cUKQq2b8WL/mAOeD2X3CGMIRoxcutKtjeksEaf3T2cFyJ3dEbNlc/xEoA 15 - dUo916ITAgMBAAGgKjAoBgkqhkiG9w0BCQ4xGzAZMBcGA1UdEQQQMA6CDGNyeXAu 16 - a2FzcC5pbzANBgkqhkiG9w0BAQsFAAOCAgEAI9S2nW5W7BVo3CXruv56L7vCB/py 17 - y1RL7nyOjb8GTnpdqfKAH6vDy9baYtQEssTr2qyRY5r8NoRnLpmcF7e3RygrsvVj 18 - PvlC7FW6OT3jiPNzVkUHsovvGyH4uhBHPX9GgtYARRPKuYtHL397R0NtQLT2r3mo 19 - 6NShiU57klAvGqUAQhLx7ZxxHCrD3ENr3i97t7oa9slYf+4bWQ0naLBxuiKTK7LR 20 - tzLPnzzTV6SjHtKmIJGT7YvlV4+I/0Ge1ueqfzlJ6sjHOzVC+rtFsUoqhRHBojrE 21 - T6yavCMA9TnxsqM857iX/WCBkUonu7ArZ2klHfVAR73LNPg5Gyxu3Y9a44YAtTpQ 22 - 0tcdrKM70rqYNUxR0iDfaHwDoq81NFfpkXDkYBPTVS2yCiocVmlh6w5XO8Ha9OSw 23 - Tl6UUwiIShUpPjA9/2X160CGPwkd9yI0/OyRhLzrSz5UWIQBAAD5nO5ok6pmJHj3 24 - 19+Gwz584e+VOpkFvq6oPVnQrOJdiihkaZjCQd++IRPwv3FjA5h7cWOJHg1FD1aj 25 - MRaY2kjZC88cjmyYt9sUMcqVSvW1gJYpbukScfHU6fOP9EiVBqoMgraloq1tb5iC 26 - rR/bj61DkiHctzmcdA5++G3QfeuXk/hbQBJ2NYx8SKm3ITVcnuBVfZgksJeQ/GL6 27 - Rk3nLWugcpJYRjE= 28 - -----END CERTIFICATE REQUEST-----
-52
web/src/tls/domain.key
··· 1 - -----BEGIN PRIVATE KEY----- 2 - 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 51 - AIPeZ9BA5epoYFkPtMa0UpiqJ9HsNNE= 52 - -----END PRIVATE KEY-----