[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.

Add stuff I already made

Too much stuff uncommited, sorry

KH (Jan 5, 2018, 9:58 PM +0100) e2467371 a92d896a

+539
+2
.gitignore
··· 1 + ferrum 2 + web/src/modules/keys.js
+10
README.md
··· 1 + # vidl-web 2 + Cryptocurrency portfolio tracker 3 + 4 + # ToDo 5 + - Empty 6 + 7 + # Deployment 8 + - **CRYP_ENV** environment variable in docker-compose.yml 9 + - Dev: **dev** 10 + - Production: **production**
+33
docker-compose.yml
··· 1 + version: "3.3" 2 + services: 3 + web: 4 + build: ./web 5 + container_name: web 6 + ports: 7 + - 80:80 8 + volumes: 9 + - ./web/src:/usr/src/app 10 + links: 11 + - db 12 + environment: 13 + - "ENV=dev" 14 + - "PROD_URL=http://cryp.kasp.io" 15 + mongo-express: 16 + image: mongo-express:0.42 17 + ports: 18 + - 8081:8081 19 + links: 20 + - db 21 + environment: 22 + - "ME_CONFIG_OPTIONS_EDITORTHEME=ambiance" 23 + - "ME_CONFIG_MONGODB_SERVER=db" 24 + - "ME_CONFIG_BASICAUTH_USERNAME=user" 25 + - "ME_CONFIG_BASICAUTH_PASSWORD=fairly long password" 26 + db: 27 + image: mongo:3.6 28 + ports: 29 + - 27017:27017 30 + restart: always 31 + # build: ./mongo 32 + # container_name: cryp-mongo 33 + # volumes:
+1
mongo/Dockerfile
··· 1 + FROM mongo:3.6
+12
web/Dockerfile
··· 1 + FROM node:8.9 2 + 3 + COPY src/package.json . 4 + 5 + RUN npm install -g nodemon@1.14.6 6 + RUN npm install 7 + 8 + WORKDIR /usr/src/app 9 + 10 + COPY src . 11 + 12 + CMD npm run $ENV
+7
web/src/modules/common.js
··· 1 + module.exports = { 2 + logErr: (code, err) => { 3 + console.log("---------- error code "+code); 4 + console.log(err); 5 + console.log("----------"); 6 + } 7 + }
+20
web/src/modules/compile.js
··· 1 + const sass = require("node-sass"); 2 + const fs = require("fs"); 3 + const fsPath = require("fs-path"); 4 + 5 + const sassSuc = "\x1b[42m[Sass]\x1b[0m "; 6 + 7 + module.exports = () => { 8 + sass.render({ 9 + file: "sass/global.sass", 10 + includePaths: ["sass"], 11 + outputStyle: "compressed" 12 + }, function(err, result) { 13 + if (err) throw err; 14 + let newFilePath = "static/global.css"; 15 + fsPath.writeFile(newFilePath, result.css, function(err) { 16 + if (err) throw err; 17 + console.log(sassSuc+"Rendered & Written file global.sass"); 18 + }); 19 + }); 20 + }
+11
web/src/modules/mongoose-models.js
··· 1 + const mongoose = require("mongoose"); 2 + const Schema = mongoose.Schema; 3 + 4 + const userSchema = new Schema({ 5 + displayName: String, 6 + googleId: String 7 + }); 8 + 9 + module.exports = { 10 + User: mongoose.model("user", userSchema) 11 + };
+37
web/src/modules/passport-setup.js
··· 1 + const passport = require("passport"); 2 + const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; 3 + const keys = require("./keys"); 4 + const User = require("./mongoose-models").User; 5 + 6 + passport.serializeUser((user, done) => { 7 + done(null, user.id); 8 + }); 9 + 10 + passport.deserializeUser((id, done) => { 11 + User.findById(id).then((resultUser) => { 12 + done(null, resultUser); 13 + }); 14 + }); 15 + 16 + passport.use(new GoogleStrategy({ 17 + clientID: keys.google.clientID, 18 + clientSecret: keys.google.clientSecret, 19 + callbackURL: "/auth/google/callback" 20 + }, (accessToken, refreshToken, profile, done) => { 21 + User.findOne({googleId: profile.id}).then((resultUser) => { 22 + if (resultUser) { 23 + // user alreaady exists 24 + console.log(`login: ${resultUser.googleId} ${resultUser.displayName}`); 25 + done(null, resultUser); 26 + } else { 27 + // new user 28 + new User({ 29 + displayName: profile.displayName, 30 + googleId: profile.id 31 + }).save().then((newUser) => { 32 + console.log(`newlogin: ${newUser.googleId} ${newUser.displayName}`); 33 + done(null, newUser); 34 + }); 35 + } 36 + }); 37 + }));
+19
web/src/modules/passport.js
··· 1 + const passport = require("passport"); 2 + const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; 3 + let callbackURL = process.env.PROD_URL; 4 + if (process.env.ENV == "dev") callbackURL = "http://localhost"; 5 + passport.use(new GoogleStrategy({ 6 + clientID: "98910954867-l9ac0hp7tns2idkj1at9ft0m21t21iqh.apps.googleusercontent.com", 7 + clientSecret: "7IOTjZJW7GKDig8uYzrFaQKl", 8 + callbackURL: callbackURL+"/auth/google/callback" 9 + }, 10 + function(accessToken, refreshToken, profile, done) { 11 + User.findOrCreate({ googleId: profile.id }, function (err, user) { 12 + return done(err, user); 13 + }); 14 + } 15 + )); 16 + 17 + module.exports = () => { 18 + app.use(passport.initialize()); 19 + };
+82
web/src/modules/routes.js
··· 1 + "use strict"; 2 + const passport = require("passport"); 3 + const logErr = require("./common").logErr; 4 + const scope = {scope: ["profile"]}; 5 + 6 + function render(app, res, pugFile, variables, callback) { 7 + app.render(pugFile, variables, (err, html) => { 8 + if (err) { 9 + callback(err); 10 + } else { 11 + variables.pageHTML = html; 12 + res.render("template", variables); 13 + } 14 + }); 15 + } 16 + 17 + module.exports = (app) => { 18 + app.all("*", (req, res, next) => { 19 + if (req.user) { 20 + res.locals.loggedIn = true; 21 + res.locals.displayName = req.user.displayName; 22 + res.locals.userID = req.user._id; 23 + } 24 + else { 25 + res.locals.loggedIn = false; 26 + } 27 + next(); 28 + }); 29 + 30 + function get(path, pugFile, variables) { 31 + if (typeof variables === "undefined") variables = {}; 32 + app.get(path, (req, res) => { 33 + function render(pugFilePrex, callback) { 34 + app.render(pugFilePrex+pugFile, variables, (err, html) => { 35 + if (err) { 36 + callback(err); 37 + } else { 38 + variables.pageHTML = html; 39 + res.render("template", variables); 40 + } 41 + }); 42 + } 43 + 44 + if (res.locals.loggedIn) { 45 + variables.displayName = req.user.displayName; 46 + render("logged-in/", (err) => { 47 + logErr(1, err); 48 + render("logged-out/", (err) => { 49 + logErr(2, err); 50 + }); 51 + }); 52 + } else { 53 + render("logged-out/", (err) => { 54 + logErr(3, err); 55 + }); 56 + } 57 + 58 + }); 59 + } 60 + 61 + get("/", "home"); 62 + 63 + app.get("/login", passport.authenticate("google", scope)); 64 + 65 + app.get("/auth/google/callback", passport.authenticate("google"), (req, res) => { 66 + res.redirect("/"); 67 + }); 68 + 69 + app.get("/logout", (req, res) => { 70 + req.logout(); 71 + res.redirect("/"); 72 + }); 73 + 74 + // app.get("/login", passport.authenticate("google", { 75 + // scope: ['https://www.googleapis.com/auth/plus.login'] 76 + // })); 77 + // 78 + // app.get("/auth/google/callback", (req, res) => { 79 + // res.redirect("/"); 80 + // }); 81 + 82 + }
+4
web/src/nodemon.json
··· 1 + { 2 + "ignore": "static", 3 + "ext": "js sass" 4 + }
+28
web/src/package.json
··· 1 + { 2 + "name": "cryp", 3 + "version": "1.0.0", 4 + "description": "cryp website", 5 + "author": "KH kasperkh.kh@gmail.com", 6 + "main": "server.js", 7 + 8 + "scripts": { 9 + "dev": "nodemon server.js", 10 + "production": "node server.js" 11 + }, 12 + "dependencies": { 13 + "nodemon": "1.14.x", 14 + 15 + "express": "4.16.x", 16 + "pug": "~2.0.0-rc.4", 17 + "node-sass": "4.7.x", 18 + "fs-path": "0.0.x", 19 + "body-parser": "1.18.x", 20 + 21 + "passport": "0.4.x", 22 + "passport-google-oauth": "1.0.x", 23 + "express-session": "1.15.x", 24 + "connect-mongo": "2.0.x", 25 + 26 + "mongoose": "~5.0.0-rc0" 27 + } 28 + }
+4
web/src/pug/logged-in/home.pug
··· 1 + p Hey there, #{displayName}! 2 + a(href="/logout") logout 3 + .results 4 + p hey
+2
web/src/pug/logged-out/home.pug
··· 1 + p Hey there, you're not logged in :/ 2 + a(href="/login") login
+26
web/src/pug/template.pug
··· 1 + doctype html 2 + html 3 + head 4 + title Cryp 5 + link(href='https://fonts.googleapis.com/css?family=Nunito:400,500', rel='stylesheet') 6 + link(href='https://fonts.googleapis.com/css?family=Rubik:400,500', rel='stylesheet') 7 + // css 8 + link(rel='stylesheet', type='text/css', href='/global.css') 9 + body 10 + .bg 11 + main.page-container !{pageHTML} 12 + //- .dialogs 13 + //- include dialogs.pug 14 + //- .fg 15 + //- main.page-container.logged-in(data-page="/") 16 + //- include music/music.pug 17 + //- main.page-container.logged-out(data-page="/") 18 + //- include login.pug 19 + //- main.page-container.logged-out.logged-in(data-page="/404") 20 + //- include 404.pug 21 + //- script 22 + //- | var path = "!{path}"; 23 + //- | var loggedIn = !{loggedIn}; 24 + //- script(src='/js.cookie-2.1.4.min.js') 25 + //- script(src='/rangeSlider-0.3.11.min.js') 26 + script(src='/global.js')
+60
web/src/sass/defaults.sass
··· 1 + html 2 + font-family: "Rubik", sans-serif 3 + * 4 + color: rgba(#FFFFFF, 0.88) 5 + font: inherit 6 + margin: 0 7 + padding: 0 8 + border: 0 9 + font-size: 16px 10 + vertical-align: baseline 11 + outline: none 12 + h1 13 + font-size: 48px 14 + h2 15 + font-size: 38px 16 + h3 17 + font-size: 28px 18 + h4 19 + font-size: 22px 20 + // body, div, span, applet, object, iframe, 21 + // h1, h2, h3, h4, h5, h6, p, blockquote, pre, 22 + // a, abbr, acronym, address, big, cite, code, 23 + // del, dfn, em, img, ins, kbd, q, s, samp, 24 + // small, strike, strong, sub, sup, tt, var, 25 + // b, u, i, center, 26 + // dl, dt, dd, ol, ul, li, 27 + // fieldset, form, label, legend, 28 + // table, caption, tbody, tfoot, thead, tr, th, td, 29 + // article, aside, canvas, details, embed, 30 + // figure, figcaption, footer, header, hgroup, 31 + // menu, nav, output, ruby, section, summary, 32 + // time, mark, audio, video 33 + 34 + a:link, a:visited, a:hover, a:active 35 + color: inherit 36 + text-decoration: none 37 + 38 + // HTML5 display-role reset for older browsers 39 + article, aside, details, figcaption, figure, 40 + footer, header, hgroup, menu, nav, section, 41 + input, textarea 42 + display: block 43 + 44 + body 45 + line-height: 1 46 + 47 + ol, ul 48 + list-style: none 49 + 50 + blockquote, q 51 + quotes: none 52 + 53 + blockquote:before, blockquote:after, 54 + q:before, q:after 55 + content: '' 56 + content: none 57 + 58 + table 59 + border-collapse: collapse 60 + border-spacing: 0
+8
web/src/sass/global.sass
··· 1 + @import "variables.sass" 2 + 3 + @import "defaults.sass" 4 + 5 + html 6 + @import "template.sass" 7 + 8 + @import "home.sass"
web/src/sass/home.sass

This is a binary file and will not be displayed.

+13
web/src/sass/template.sass
··· 1 + .bg 2 + z-index: -1 3 + .page-container 4 + position: relative 5 + z-index: 5 6 + 7 + .bg 8 + position: absolute 9 + width: 100% 10 + height: 100% 11 + // background-color: #212629 12 + background-color: #22272a 13 + // background-color: #111111
+27
web/src/sass/variables.sass
··· 1 + // shadow elevation 2 + $shadow-1: 0px 1px 2px 0px rgba(0,0,0,0.24) 3 + $shadow-1-inset-top: inset 0px 21px 2px -20px rgba(0,0,0,0.24) 4 + $shadow-1-inset-bottom: inset 0px -21px 2px -20px rgba(0,0,0,0.24) 5 + $shadow-2: 0px 2px 4px 0px rgba(0,0,0,0.24) 6 + $shadow-2-left: -20px 0px 4px -20px rgba(0,0,0,0.24) 7 + $shadow-2-inset-top: inset 0px 22px 4px -20px rgba(0,0,0,0.24) 8 + $shadow-2-inset-bottom: inset 0px -22px 4px -20px rgba(0,0,0,0.24) 9 + $shadow-3: 0px 3px 6px 0px rgba(0,0,0,0.24) 10 + $shadow-3-inset-top: inset 0px 23px 6px -20px rgba(0,0,0,0.24) 11 + $shadow-4: 0px 4px 8px 0px rgba(0,0,0,0.24) 12 + $shadow-4-inset-top: inset 0px 24px 8px -20px rgba(0,0,0,0.24) 13 + $shadow-4-inset-bottom: inset 0px -24px 8px -20px rgba(0,0,0,0.24) 14 + $shadow-5: 0px 6px 10px 0px rgba(0,0,0,0.24) 15 + $shadow-5-inset-top: inset 0px 26px 10px -20px rgba(0,0,0,0.24) 16 + // $shadow-1: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24) 17 + // $shadow-2: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23) 18 + // $shadow-3: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23) 19 + // $shadow-4: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22) 20 + // $shadow-5: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22) 21 + 22 + // transitions 23 + $transition: .15s cubic-bezier(0.4, 0.0, 0.2, 1.0) 24 + $transition-short: .10s cubic-bezier(0.4, 0.0, 0.2, 1.0) 25 + $transition-long: .30s cubic-bezier(0.4, 0.0, 0.2, 1.0) 26 + $transition-long-in: .30s cubic-bezier(0.0, 0.0, 0.2, 1.0) 27 + $transition-long-out: .30s cubic-bezier(0.4, 0.0, 1.0, 1.0)
+90
web/src/server.js
··· 1 + "use strict"; 2 + // modules 3 + const bodyParser = require("body-parser"); 4 + // express 5 + const express = require("express"); 6 + const app = express(); 7 + // local modules 8 + if (process.env.ENV == "dev") require("./modules/compile")(); 9 + 10 + // load view engine 11 + app.set("views", "pug"); 12 + app.set("view engine", "pug"); 13 + 14 + // static content 15 + app.use("/", express.static("static", { redirect: false })); 16 + app.use("/", express.static("static/favicon", { redirect: false })); 17 + 18 + // parse application/x-www-form-urlencoded 19 + app.use(bodyParser.urlencoded({ extended: false })); 20 + // parse application/json 21 + app.use(bodyParser.json()); 22 + 23 + // mongoose 24 + const mongoose = require("mongoose"); 25 + mongoose.connect("mongodb://db/cryp"); 26 + const db = mongoose.connection; 27 + const dbSuc = "\x1b[42m[Mongoose]\x1b[0m "; 28 + db.on("error", console.error.bind(console, "connection error:")); 29 + db.once("open", () => { 30 + console.log(dbSuc+"connected to MongoDB"); 31 + }); 32 + 33 + // passport 34 + const passport = require("passport"); 35 + const passportSetup = require("./modules/passport-setup"); 36 + 37 + const session = require("express-session"); 38 + const MongoStore = require("connect-mongo")(session); 39 + app.use(session({ 40 + // key: "sess", 41 + secret: "tomatonanaboy69:o", 42 + store: new MongoStore({ 43 + mongooseConnection: mongoose.connection, 44 + ttl: 60*60*24*90, 45 + touchAfter: 60*60*24 46 + }), 47 + resave: false, 48 + saveUninitialized: false//, 49 + // cookie: {} 50 + })); 51 + app.use(passport.initialize()); 52 + app.use(passport.session()); 53 + // const passport = require("passport"); 54 + // const MongoStore = require("connect-mongo")(session); 55 + // app.use(session({ 56 + // // key: "sess", 57 + // secret: "bananaboy69", 58 + // store: new MongoStore({ 59 + // mongooseConnection: mongoose.connection, 60 + // ttl: 60*60*24*90, 61 + // touchAfter: 60*60*24 62 + // }), 63 + // resave: false, 64 + // saveUninitialized: false//, 65 + // // cookie: {} 66 + // })); 67 + // const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; 68 + // let callbackURL = process.env.PROD_URL; 69 + // if (process.env.ENV == "dev") callbackURL = "http://localhost"; 70 + // passport.use(new GoogleStrategy({ 71 + // clientID: "98910954867-l9ac0hp7tns2idkj1at9ft0m21t21iqh.apps.googleusercontent.com", 72 + // clientSecret: "7IOTjZJW7GKDig8uYzrFaQKl", 73 + // callbackURL: callbackURL+"/auth/google/callback" 74 + // }, (accessToken, refreshToken, profile, done) => { 75 + // User.findOrCreate({ googleId: profile.id }, function (err, user) { 76 + // console.log("err"); 77 + // console.log(err); 78 + // console.log("user"); 79 + // console.log(user); 80 + // return done(err, user); 81 + // }); 82 + // })); 83 + 84 + // routes 85 + require("./modules/routes")(app); 86 + 87 + // start server 88 + const server = app.listen(80, () => { 89 + console.log("Express server listening on 80"); 90 + });
+1
web/src/static/global.css
··· 1 + html{font-family:"Rubik", sans-serif}*{color:rgba(255,255,255,0.88);font:inherit;margin:0;padding:0;border:0;font-size:16px;vertical-align:baseline;outline:none}h1{font-size:48px}h2{font-size:38px}h3{font-size:28px}h4{font-size:22px}a:link,a:visited,a:hover,a:active{color:inherit;text-decoration:none}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,input,textarea{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}html .bg{z-index:-1}html .page-container{position:relative;z-index:5}html .bg{position:absolute;width:100%;height:100%;background-color:#22272a}
+42
web/src/static/global.js
··· 1 + { 2 + type: "", 3 + buy: [], 4 + sell: [], 5 + fee: [], 6 + exchange: "", 7 + group: "", 8 + note: "", 9 + date: new Date("") 10 + } 11 + let json = [ 12 + { 13 + type: "fiatBuy", 14 + buy: [0.04073887, "BTC"], 15 + sell: [932.03, "NOK"], 16 + fee: [], 17 + exchange: "Bittrex", 18 + group: "", 19 + note: "via Anycoin Direct", 20 + date: new Date("2017-07-25 11:04:48") 21 + }, 22 + { 23 + type: "trade", 24 + buy: [6120.03355798, "SC"], 25 + sell: [0.02006253, "BTC"], 26 + fee: [0.00005003, "BTC"], 27 + exchange: "Bittrex", 28 + group: "", 29 + note: "", 30 + date: new Date("2017-07-27 21:49:53") 31 + }, 32 + { 33 + type: "moveExchange", 34 + amount: [100, "SC"] 35 + fee: [0.1, "SC"], 36 + fromExchange: "Bittrex", 37 + toExchange: "SC Wallet", 38 + group: "", 39 + note: "", 40 + date: new Date("2017-07-27 22:00:55") 41 + } 42 + ];