[READ-ONLY] Mirror of https://github.com/probablykasper/lumix. Art website (unfinished)
art website
0

Configure Feed

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

Setup (taken from Cryp) + basic homepage start

KH (Feb 23, 2018, 11:27 PM +0100) 37ecb444 7eb80987

+870
+9
.env
··· 1 + LUMIX_ENV=dev 2 + 3 + CERT_DOMAIN=lumix.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
+3
.gitignore
··· 1 + web/letsencrypt 2 + **/keys.js 3 + db/db
+29
README.md
··· 1 + # Lumix 2 + Art website 3 + 4 + ### Get Started 5 + - Install Docker Compose if you do not already have it. 6 + - Set your environment variables in `.env`. This assumes your server only uses *one* domain. 7 + - `LUMIX_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: 11 + 1. Go to the [APIs section of GCP](https://console.cloud.google.com/apis/credentials) and create a project, then select it. 12 + 2. Click "Create credentials" and "OAuth client ID". 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`. 14 + 4. Press "Create", and you'll be presented with your client ID and secret. 15 + 16 + Your keys.js file should have this format: 17 + ```javascript 18 + module.exports = { 19 + google: { 20 + clientID: "", 21 + clientSecret: "", 22 + } 23 + } 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`.
+62
docker-compose.yml
··· 1 + version: "3.3" 2 + services: 3 + web: 4 + build: 5 + context: ./web 6 + dockerfile: web.Dockerfile 7 + env_file: 8 + - .env 9 + ports: 10 + - ${PORT_INSECURE}:${PORT_INSECURE} 11 + - ${PORT_SECURE}:${PORT_SECURE} 12 + depends_on: 13 + - db 14 + - mongo-express 15 + restart: on-failure 16 + volumes: 17 + - ./web:/usr/src/app 18 + 19 + mongo-express: 20 + image: mongo-express:0.42 21 + ports: 22 + - ${PORT_MONGO_EXPRESS}:${PORT_MONGO_EXPRESS} 23 + depends_on: 24 + - db 25 + restart: on-failure 26 + environment: 27 + - "ME_CONFIG_OPTIONS_EDITORTHEME=ambiance" 28 + - "ME_CONFIG_MONGODB_SERVER=db" 29 + - "ME_CONFIG_BASICAUTH_USERNAME=user" 30 + - "ME_CONFIG_BASICAUTH_PASSWORD=fairly long password" 31 + 32 + db: 33 + image: mongo:3.6 34 + ports: 35 + - 27017:27017 36 + restart: on-failure 37 + volumes: 38 + - ./db/db:/data/db 39 + restart: always 40 + 41 + letsencrypt-init: 42 + # https://stackoverflow.com/questions/39846649/how-to-use-lets-encrypt-with-docker-container-based-on-the-node-js-image 43 + image: certbot/certbot:v0.21.1 44 + env_file: 45 + - .env 46 + ports: 47 + - 80:80 48 + - 443:443 49 + volumes: 50 + - ./web/letsencrypt/etc/letsencrypt:/etc/letsencrypt 51 + - ./web/letsencrypt/var/lib/letsencrypt:/var/lib/letsencrypt 52 + - ./web/letsencrypt/usr/share/nginx/html:/usr/share/nginx/html 53 + command: certonly -n -d ${CERT_DOMAIN} -m ${CERT_EMAIL} --standalone --agree-tos 54 + letsencrypt-renew: 55 + image: certbot/certbot:v0.21.1 56 + env_file: 57 + - .env 58 + volumes: 59 + - ./web/letsencrypt/etc/letsencrypt:/etc/letsencrypt 60 + - ./web/letsencrypt/var/lib/letsencrypt:/var/lib/letsencrypt 61 + - ./web/letsencrypt/usr/share/nginx/html:/usr/share/nginx/html 62 + command: certonly -n -d 2.kasp.io --webroot -w /usr/share/nginx/html --agree-tos
+8
web/js/global.js
··· 1 + // search 2 + const searchField = $(".search")[0]; 3 + $(".search").keypress((e) => { 4 + if (e.which == 13) { 5 + const searchQuery = searchField.value; 6 + window.location = `/search/${searchQuery}`; 7 + } 8 + });
+11
web/node/log-err.js
··· 1 + module.exports = (code, err) => { 2 + console.error( 3 + `----- =-=-=-=-=-=-=-=- ${code} -=-=-=-=-=-=-=-= -----`, 4 + "\n", 5 + err, 6 + "\n", 7 + new Error().stack, 8 + "\n", 9 + `----- ================ ${code} ================ -----`, 10 + ) 11 + }
+22
web/node/mongoose-models.js
··· 1 + const mongoose = require("mongoose"); 2 + const Schema = mongoose.Schema; 3 + 4 + const imageSchema = new Schema({ 5 + uploaderGoogleId: String, 6 + date: String, 7 + views: Number, 8 + downloads: Number, 9 + likes: Number, 10 + tags: [String], 11 + }, { typeKey: "$Type"}); 12 + 13 + const userSchema = new Schema({ 14 + displayName: String, 15 + googleId: String, 16 + profilePictureURL: String, 17 + // images: [imageSchema], 18 + }, { typeKey: "$Type" }); 19 + 20 + module.exports = { 21 + User: mongoose.model("User", userSchema), 22 + };
+38
web/node/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 + profilePictureURL: profile.photos[0].value 32 + }).save().then((newUser) => { 33 + console.log(`newlogin: ${newUser.googleId} ${newUser.displayName}`); 34 + done(null, newUser); 35 + }); 36 + } 37 + }); 38 + }));
+108
web/node/routes.js
··· 1 + "use strict"; 2 + const passport = require("passport"); 3 + 4 + function render(app, res, pugFile, variables, callback) { 5 + app.render(pugFile, variables, (err, html) => { 6 + if (err) { 7 + callback(err); 8 + } else { 9 + variables.pageHTML = html; 10 + res.render("template", variables); 11 + } 12 + }); 13 + } 14 + 15 + function jsonRes(res, one, two) { 16 + let resObj = {}; 17 + if (one == "err") { 18 + resObj = { 19 + err: { 20 + code: null, 21 + msg: null 22 + } 23 + }; 24 + } else if (one) { 25 + resObj = one; 26 + } 27 + res.json(resObj); 28 + } 29 + 30 + module.exports = (app) => { 31 + 32 + app.all("*", (req, res, next) => { 33 + if (req.user) { 34 + res.locals.loggedIn = true; 35 + res.locals.displayName = req.user.displayName; 36 + res.locals.userID = req.user._id; 37 + res.locals.transactions = req.transactions; 38 + } 39 + else { 40 + res.locals.loggedIn = false; 41 + } 42 + next(); 43 + }); 44 + 45 + function get(path, pugFile, variables = {}) { 46 + // "path", "pugFile" 47 + // "path", "pugFile", {variables} 48 + // "path", "pugFileLoggedIn", "pugFileLoggedOut" 49 + let loggedOutPugFile; 50 + if (typeof variables === "string") { 51 + loggedOutPugFile = variables; 52 + variables = {}; 53 + } else { 54 + loggedOutPugFile = pugFile; 55 + } 56 + app.get(path, (req, res) => { 57 + function render(file, callback) { 58 + app.render(file, variables, (err, html) => { 59 + if (err) { 60 + callback(err); 61 + } else { 62 + variables.pageHTML = html; 63 + res.render("template", variables); 64 + } 65 + }); 66 + } 67 + 68 + variables.page = pugFile; 69 + variables.loggedIn = res.locals.loggedIn; 70 + if (res.locals.loggedIn) { 71 + variables.displayName = req.user.displayName; 72 + variables.profilePictureURL = req.user.profilePictureURL; 73 + variables.transactions = req.user.transactions; 74 + render("logged-in/"+pugFile, (err) => { 75 + logErr(72001, err); 76 + render("logged-out/"+loggedOutPugFile, (err) => { 77 + logErr(72002, err); 78 + }); 79 + }); 80 + } else { 81 + render("logged-out/"+loggedOutPugFile, (err) => { 82 + logErr(72003, err); 83 + }); 84 + } 85 + 86 + }); 87 + } 88 + 89 + const scope = {scope: ["profile"]}; 90 + app.get("/login", passport.authenticate("google", scope)); 91 + 92 + app.get("/auth/google/callback", passport.authenticate("google"), (req, res) => { 93 + res.redirect("/"); 94 + }); 95 + 96 + app.get("/logout", (req, res) => { 97 + req.logout(); 98 + res.redirect("/"); 99 + }); 100 + 101 + get("/", "home"); 102 + 103 + // get("/balance", "balance"); 104 + // get("/gains", "gains"); 105 + // 106 + // get("/transactions", "transactions"); 107 + 108 + }
+7
web/nodemon.json
··· 1 + { 2 + "watch": [ 3 + "server.js", 4 + "node" 5 + ], 6 + "ext": "js" 7 + }
+39
web/package.json
··· 1 + { 2 + "name": "lumix", 3 + "version": "1.0.0", 4 + "description": "lumix website", 5 + "author": "KH kasperkh.kh@gmail.com", 6 + "main": "server.js", 7 + 8 + "scripts": { 9 + "build-dev": "webpack --config webpack.config.js --watch", 10 + "start-dev": "nodemon server.js", 11 + "dev": "npm-run-all --parallel build-dev start-dev", 12 + 13 + "build-production": "webpack --config webpack.config.js", 14 + "start-production": "node server.js", 15 + "production": "npm-run-all build-production start-production" 16 + }, 17 + "dependencies": { 18 + "webpack": "3.11.x", 19 + "node-sass": "4.7.x", 20 + "extract-text-webpack-plugin": "3.0.x", 21 + "css-loader": "0.28.x", 22 + "sass-loader": "6.0.x", 23 + "babel-loader": "7.1.x", 24 + "babel-register": "6.26.x", 25 + "babel-preset-env": "1.6.x", 26 + 27 + "express": "4.16.x", 28 + "redirect-https": "1.1.x", 29 + "pug": "~2.0.0-rc.4", 30 + "body-parser": "1.18.x", 31 + 32 + "passport": "0.4.x", 33 + "passport-google-oauth": "1.0.x", 34 + "express-session": "1.15.x", 35 + "connect-mongo": "2.0.x", 36 + 37 + "mongoose": "5.0.x" 38 + } 39 + }
+3
web/pug/logged-out/home.pug
··· 1 + .center-container 2 + p.center-logo Lumix 3 + p.tagline The place you put your art
+41
web/pug/template.pug
··· 1 + doctype html 2 + html 3 + head 4 + title Lumix 5 + link(href='https://fonts.googleapis.com/css?family=Roboto: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 + header.site-header 11 + a(href="/").header-logo Lumix 12 + input(placeholder="Search").search 13 + .menu-bar 14 + a(href="/login").menu-bar-item Login 15 + //- if profilePictureURL 16 + //- .account-icon 17 + //- img.account-icon(src=profilePictureURL) 18 + //- .account-box 19 + //- .spacer 20 + //- a.account-box-item.settings(href="/settings") 21 + //- <svg fill="#3F3F3F" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> 22 + //- <path d="M0 0h24v24H0z" fill="none"/> 23 + //- <path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/> 24 + //- </svg> 25 + //- .item-text.settings Settings 26 + //- a.account-box-item.logout(href="/logout") 27 + //- <svg fill="#3F3F3F" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> 28 + //- <path d="M0 0h24v24H0z" fill="none"/> 29 + //- <path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/> 30 + //- </svg> 31 + //- .item-text.logout Logout 32 + //- .spacer 33 + 34 + main.page-container !{pageHTML} 35 + script(src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js") 36 + script 37 + | const loggedIn = !{loggedIn}; 38 + | const page = "!{page}"; 39 + if loggedIn && transactions 40 + | let transactions = [!{transactions}]; 41 + script(src="/global.js")
+59
web/sass/defaults.sass
··· 1 + table 2 + border-collapse: collapse 3 + border-spacing: 0 4 + * 5 + color: $black 6 + font: inherit 7 + margin: 0 8 + padding: 0 9 + border: 0 10 + font-size: 16px 11 + vertical-align: baseline 12 + outline: none 13 + h1 14 + font-size: 48px 15 + h2 16 + font-size: 38px 17 + h3 18 + font-size: 28px 19 + h4 20 + font-size: 22px 21 + // body, div, span, applet, object, iframe, 22 + // h1, h2, h3, h4, h5, h6, p, blockquote, pre, 23 + // a, abbr, acronym, address, big, cite, code, 24 + // del, dfn, em, img, ins, kbd, q, s, samp, 25 + // small, strike, strong, sub, sup, tt, var, 26 + // b, u, i, center, 27 + // dl, dt, dd, ol, ul, li, 28 + // fieldset, form, label, legend, 29 + // table, caption, tbody, tfoot, thead, tr, th, td, 30 + // article, aside, canvas, details, embed, 31 + // figure, figcaption, footer, header, hgroup, 32 + // menu, nav, output, ruby, section, summary, 33 + // time, mark, audio, video 34 + img 35 + display: block 36 + 37 + a:link, a:visited, a:hover, a:active 38 + color: inherit 39 + text-decoration: none 40 + 41 + // HTML5 display-role reset for older browsers 42 + article, aside, details, figcaption, figure, 43 + footer, header, hgroup, menu, nav, section, 44 + input, textarea 45 + display: block 46 + 47 + body 48 + line-height: 1 49 + 50 + ol, ul 51 + list-style: none 52 + 53 + blockquote, q 54 + quotes: none 55 + 56 + blockquote:before, blockquote:after, 57 + q:before, q:after 58 + content: '' 59 + content: none
+11
web/sass/global.sass
··· 1 + @import "variables.sass" 2 + 3 + @import "defaults.sass" 4 + 5 + @import "template.sass" 6 + 7 + html 8 + 9 + @import "home.sass" 10 + // @import "buttons.sass" 11 + // @import "cards.sass"
+16
web/sass/home.sass
··· 1 + .center-container 2 + position: absolute 3 + width: 100% 4 + height: 100% 5 + min-height: 400px 6 + left: 0px 7 + top: 0px 8 + 9 + display: flex 10 + justify-content: center 11 + align-items: center 12 + flex-direction: column 13 + p.center-logo 14 + font-size: 128px 15 + p.tagline 16 + font-size: 16px
+27
web/sass/template.sass
··· 1 + html 2 + font-family: "Rubik", sans-serif 3 + body 4 + background-color: $white 5 + display: grid 6 + main.page-container 7 + margin: 30px 8 + 9 + header.site-header 10 + z-index: 5 11 + height: $header-height 12 + // background-color: #16C19D 13 + // background-color: #5A73E2 14 + // background-color: #2A2A2A 15 + display: flex 16 + align-items: center 17 + justify-content: space-between 18 + padding: 0px 20px 19 + color: $black 20 + a.header-logo 21 + font-size: 38px 22 + padding: 8px 23 + input.search 24 + padding: 10px 14px 25 + border-radius: 5px 26 + width: 250px 27 + background-color: $white-dark
+48
web/sass/variables.sass
··· 1 + $header-height: 70px 2 + $white: #FFFFFF 3 + $white-dark: #F9F9F9 4 + $black: #3F3F3F 5 + $tooltip-bg: #3c4554 6 + 7 + // shadow elevation 8 + $shadow-0: 0px 1px 2px 0px rgba(0,0,0,0) 9 + $shadow-1: 0px 1px 2px 0px rgba(0,0,0,0.24) 10 + $shadow-1-inset-top: inset 0px 21px 2px -20px rgba(0,0,0,0.24) 11 + $shadow-1-inset-bottom: inset 0px -21px 2px -20px rgba(0,0,0,0.24) 12 + $shadow-2: 0px 2px 4px 0px rgba(0,0,0,0.24) 13 + $shadow-2-left: -20px 0px 4px -20px rgba(0,0,0,0.24) 14 + $shadow-2-inset-top: inset 0px 22px 4px -20px rgba(0,0,0,0.24) 15 + $shadow-2-inset-bottom: inset 0px -22px 4px -20px rgba(0,0,0,0.24) 16 + $shadow-3: 0px 3px 6px 0px rgba(0,0,0,0.24) 17 + $shadow-3-inset-top: inset 0px 23px 6px -20px rgba(0,0,0,0.24) 18 + $shadow-4: 0px 4px 8px 0px rgba(0,0,0,0.24) 19 + $shadow-4-inset-top: inset 0px 24px 8px -20px rgba(0,0,0,0.24) 20 + $shadow-4-inset-bottom: inset 0px -24px 8px -20px rgba(0,0,0,0.24) 21 + $shadow-5: 0px 6px 10px 0px rgba(0,0,0,0.24) 22 + $shadow-5-inset-top: inset 0px 26px 10px -20px rgba(0,0,0,0.24) 23 + // $shadow-1: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24) 24 + // $shadow-2: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23) 25 + // $shadow-3: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23) 26 + // $shadow-4: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22) 27 + // $shadow-5: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22) 28 + 29 + // transitions 30 + $transition: .15s cubic-bezier(0.4, 0.0, 0.2, 1.0) 31 + $transition-15: .15s cubic-bezier(0.4, 0.0, 0.2, 1.0) 32 + 33 + $transition-10: .10s cubic-bezier(0.4, 0.0, 0.2, 1.0) 34 + 35 + $transition-10: .10s cubic-bezier(0.4, 0.0, 0.2, 1.0) 36 + $transition-10-in: .10s cubic-bezier(0.0, 0.0, 0.2, 1.0) 37 + $transition-10-in: .10s cubic-bezier(0.0, 0.0, 0.2, 1.0) 38 + $transition-10-out: .10s cubic-bezier(0.4, 0.0, 1.0, 1.0) 39 + 40 + $transition-20: .20s cubic-bezier(0.4, 0.0, 0.2, 1.0) 41 + $transition-20-in: .20s cubic-bezier(0.0, 0.0, 0.2, 1.0) 42 + $transition-20-in: .20s cubic-bezier(0.0, 0.0, 0.2, 1.0) 43 + $transition-20-out: .20s cubic-bezier(0.4, 0.0, 1.0, 1.0) 44 + 45 + $transition-30: .30s cubic-bezier(0.4, 0.0, 0.2, 1.0) 46 + $transition-30-in: .30s cubic-bezier(0.0, 0.0, 0.2, 1.0) 47 + $transition-30-in: .30s cubic-bezier(0.0, 0.0, 0.2, 1.0) 48 + $transition-30-out: .30s cubic-bezier(0.4, 0.0, 1.0, 1.0)
+83
web/server.js
··· 1 + "use strict"; 2 + const express = require("express"); 3 + const fs = require("fs"); 4 + global.dir = (dirPath) => { 5 + return require("path").resolve(__dirname, dirPath); 6 + } 7 + global.logErr = require("./node/log-err.js"); 8 + const PORT_INSECURE = process.env.PORT_INSECURE; 9 + const PORT_SECURE = process.env.PORT_SECURE; 10 + 11 + // http 12 + (() => { 13 + 14 + const server = require("http").createServer(); 15 + server.on("request", require("redirect-https")({ 16 + port: PORT_SECURE, 17 + body: "<!-- Please use HTTPS instead. That's a \"you don't have a choice\", not a \"please\". -->" 18 + })); 19 + server.listen(PORT_INSECURE, () => { 20 + console.log(); 21 + }); 22 + 23 + })(); 24 + 25 + (() => { 26 + 27 + const app = express(); 28 + 29 + // load view engine 30 + app.set("views", dir("pug")); 31 + app.set("view engine", "pug"); 32 + 33 + // static content 34 + app.use("/", express.static(dir("static"), { redirect: false })); 35 + app.use("/", express.static(dir("static/favicon"), { redirect: false })); 36 + 37 + const bodyParser = require("body-parser"); 38 + // parse application/x-www-form-urlencoded 39 + app.use(bodyParser.urlencoded({ extended: false })); 40 + // parse application/json 41 + app.use(bodyParser.json({ type: "application/json" })); 42 + 43 + // mongoose 44 + const mongoose = require("mongoose"); 45 + mongoose.connect("mongodb://db/cryp"); 46 + const db = mongoose.connection; 47 + const dbSuc = "\x1b[42m[Mongoose]\x1b[0m "; 48 + db.on("error", console.error.bind(console, "connection error:")); 49 + db.once("open", () => { 50 + console.log(dbSuc+"connected to MongoDB"); 51 + }); 52 + 53 + // passport 54 + const passport = require("passport"); 55 + const passportSetup = require("./node/passport-setup"); 56 + const session = require("express-session"); 57 + const MongoStore = require("connect-mongo")(session); 58 + app.use(session({ 59 + // key: "sess", 60 + secret: "tomatonanaboy69:o", 61 + store: new MongoStore({ 62 + mongooseConnection: mongoose.connection, 63 + ttl: 60*60*24*90, 64 + touchAfter: 60*60*24 65 + }), 66 + resave: false, 67 + saveUninitialized: false 68 + })); 69 + app.use(passport.initialize()); 70 + app.use(passport.session()); 71 + 72 + // routes 73 + require("./node/routes")(app); 74 + 75 + const httpsOptions = { 76 + key: fs.readFileSync(dir(`letsencrypt/etc/letsencrypt/live/${process.env.CERT_DOMAIN}/privkey.pem`)), 77 + cert: fs.readFileSync(dir(`letsencrypt/etc/letsencrypt/live/${process.env.CERT_DOMAIN}/cert.pem`)) 78 + }; 79 + require("https").createServer(httpsOptions, app).listen(PORT_SECURE, () => { 80 + console.log("app listening on port "+PORT_SECURE); 81 + }); 82 + 83 + })();
+1
web/static/global.css
··· 1 + table{border-collapse:collapse;border-spacing:0}*{color:#3f3f3f;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}img{display:block}a:active,a:hover,a:link,a:visited{color:inherit;text-decoration:none}article,aside,details,figcaption,figure,footer,header,hgroup,input,menu,nav,section,textarea{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}html{font-family:Rubik,sans-serif}body{background-color:#fff;display:grid}main.page-container{margin:30px}header.site-header{z-index:5;height:70px;display:flex;align-items:center;justify-content:space-between;padding:0 20px;color:#3f3f3f}header.site-header a.header-logo{font-size:38px;padding:8px}header.site-header input.search{padding:10px 14px;border-radius:5px;width:250px;background-color:#f9f9f9}html .center-container{position:absolute;width:100%;height:100%;min-height:400px;left:0;top:0;display:flex;justify-content:center;align-items:center;flex-direction:column}html .center-container p.center-logo{font-size:128px}html .center-container p.tagline{font-size:16px}
+83
web/static/global.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, __webpack_require__) { 69 + 70 + "use strict"; 71 + 72 + 73 + // search 74 + var searchField = $(".search")[0]; 75 + $(".search").keypress(function (e) { 76 + if (e.which == 13) { 77 + var searchQuery = searchField.value; 78 + window.location = "/search/" + searchQuery; 79 + } 80 + }); 81 + 82 + /***/ }) 83 + /******/ ]);
+73
web/static/sass.webpack.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 + /******/ ]);
+15
web/web.Dockerfile
··· 1 + FROM node:8.9 2 + 3 + COPY package.json . 4 + 5 + # install CLI stuff globally 6 + RUN npm install -g nodemon@1.14.x 7 + RUN npm install -g webpack@3.10.x 8 + RUN npm install -g npm-run-all@4.1.x 9 + RUN npm install 10 + 11 + WORKDIR /usr/src/app 12 + 13 + COPY . . 14 + 15 + CMD npm run ${LUMIX_ENV}
+74
web/webpack.config.js
··· 1 + const path = require("path"); 2 + const webpack = require("webpack"); 3 + const ExtractTextPlugin = require("extract-text-webpack-plugin"); 4 + 5 + let ifDev = false; 6 + let ifProduction = true; 7 + if (process.env.CRYP_ENV == "dev") { 8 + ifDev = true; 9 + ifProduction = false; 10 + } 11 + 12 + module.exports = [ 13 + { 14 + context: path.resolve(__dirname), 15 + entry: "./js/global.js", 16 + output: { 17 + filename: "global.js", 18 + path: path.resolve(__dirname, "static") 19 + }, 20 + module: { 21 + loaders: [{ 22 + test: /\.js$/, 23 + loader: "babel-loader", 24 + query: { 25 + presets: ["env"] 26 + } 27 + }] 28 + }, 29 + plugins: (() => { 30 + let arr = []; 31 + if (ifProduction) { 32 + arr.push( 33 + new webpack.optimize.UglifyJsPlugin({ 34 + compress: { 35 + warnings: false, 36 + drop_console: false, 37 + } 38 + }) 39 + ); 40 + } 41 + })() 42 + }, 43 + { 44 + context: path.resolve(__dirname), 45 + entry: "./sass/global.sass", 46 + output: { 47 + filename: "sass.webpack.js", 48 + path: path.resolve(__dirname, "static") 49 + }, 50 + module: { 51 + rules: [{ 52 + test: /\.sass$/, 53 + use: ExtractTextPlugin.extract({ 54 + use: [ 55 + { 56 + loader: "css-loader", 57 + options: { 58 + minimize: ifProduction 59 + } 60 + }, 61 + { 62 + loader: "sass-loader" 63 + } 64 + ] 65 + }) 66 + }] 67 + }, 68 + plugins: [ 69 + new ExtractTextPlugin({ 70 + filename: "global.css" 71 + }) 72 + ] 73 + } 74 + ]