Commit 98576155 authored by NGPixel's avatar NGPixel

Integration to Requarks Core

parent 67441908
...@@ -4,15 +4,16 @@ ...@@ -4,15 +4,16 @@
// Licensed under AGPLv3 // Licensed under AGPLv3
// =========================================== // ===========================================
global.ROOTPATH = __dirname;
global.PROCNAME = 'AGENT'; global.PROCNAME = 'AGENT';
global.ROOTPATH = __dirname;
global.CORE_PATH = ROOTPATH + '/../core/';
global.IS_DEBUG = process.env.NODE_ENV === 'development';
// ---------------------------------------- // ----------------------------------------
// Load Winston // Load Winston
// ---------------------------------------- // ----------------------------------------
var _isDebug = process.env.NODE_ENV === 'development'; global.winston = require(CORE_PATH + 'core-libs/winston')(IS_DEBUG);
global.winston = require('./libs/winston')(_isDebug);
// ---------------------------------------- // ----------------------------------------
// Load global modules // Load global modules
...@@ -20,8 +21,8 @@ global.winston = require('./libs/winston')(_isDebug); ...@@ -20,8 +21,8 @@ global.winston = require('./libs/winston')(_isDebug);
winston.info('[AGENT] Background Agent is initializing...'); winston.info('[AGENT] Background Agent is initializing...');
var appconfig = require('./libs/config')('./config.yml'); var appconfig = require(CORE_PATH + 'core-libs/config')('./config.yml');
global.db = require('./libs/mongo').init(appconfig); global.db = require(CORE_PATH + 'core-libs/mongodb').init(appconfig);
global.upl = require('./libs/uploads-agent').init(appconfig); global.upl = require('./libs/uploads-agent').init(appconfig);
global.git = require('./libs/git').init(appconfig); global.git = require('./libs/git').init(appconfig);
global.entries = require('./libs/entries').init(appconfig); global.entries = require('./libs/entries').init(appconfig);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
//@import './layout/_fonts'; @import 'core-client/scss/core';
@import './layout/_base'; @import 'core-client/scss/components/alert';
@import './layout/_mixins'; @import 'core-client/scss/components/button';
@import 'core-client/scss/components/form';
@import 'core-client/scss/components/grid';
@import 'core-client/scss/components/hero';
@import 'core-client/scss/components/markdown-content';
@import 'core-client/scss/components/modal';
@import 'core-client/scss/components/nav';
@import 'core-client/scss/components/sidebar';
@import 'core-client/scss/components/typography';
@import './libs/bulma/bulma';
@import './libs/twemoji-awesome'; @import './libs/twemoji-awesome';
@import './libs/animate.min.css';
@import './libs/jquery-contextmenu'; @import './libs/jquery-contextmenu';
@import './components/_alerts'; //@import './components/_editor';
@import './components/_editor';
@import './layout/_header'; @import './layout/_header';
@import './layout/_footer'; @import './layout/_footer';
@import './layout/_content'; //@import './layout/_content';
@import './pages/_account'; //@import './pages/_account';
\ No newline at end of file \ No newline at end of file
#alerts {
position: fixed;
top: 60px;
right: 10px;
width: 350px;
z-index: 10;
text-shadow: 1px 1px 0 rgba(0,0,0,0.1);
.notification {
animation: 0.5s ease slideInRight;
margin-top: 5px;
&.exit {
animation: 0.5s ease fadeOutRight;
}
}
h3 {
font-size: 16px;
font-size: 500;
}
}
\ No newline at end of file
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
[v-cloak] {
display: none;
}
\ No newline at end of file
#root {
padding-top: 52px;
}
#page-type-view > section { #page-type-view > section {
transition: background-color .5s ease; transition: background-color .5s ease;
&.blurred { &.blurred {
background-color: $grey-lighter; background-color: mc('grey', '50');
} }
} }
...@@ -36,26 +33,26 @@ ...@@ -36,26 +33,26 @@
.mkcontent { .mkcontent {
h1 { h1 {
border-bottom: 1px dotted $blue; border-bottom: 1px dotted mc('blue', '500');
padding-bottom: 4px; padding-bottom: 4px;
font-weight: 400; font-weight: 400;
color: desaturate($blue, 20%); color: desaturate(mc('blue', '500'), 20%);
} }
h2 { h2 {
border-bottom: 1px dotted $grey-light; border-bottom: 1px dotted mc('grey', '100');
padding-bottom: 4px; padding-bottom: 4px;
font-weight: 400; font-weight: 400;
color: desaturate($purple, 20%); color: desaturate(mc('purple', '500'), 20%);
} }
a.toc-anchor { a.toc-anchor {
font-size: 80%; font-size: 80%;
color: $blue; color: mc('blue', '500');
border-bottom: none; border-bottom: none;
&:visited { &:visited {
color: $purple !important; color: mc('purple', '500') !important;
} }
} }
...@@ -70,7 +67,7 @@ ...@@ -70,7 +67,7 @@
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
text-decoration: inherit; text-decoration: inherit;
color: $grey; color: mc('grey', '500');
font-size: 14px; font-size: 14px;
position: absolute; position: absolute;
top: 0; top: 0;
...@@ -81,10 +78,10 @@ ...@@ -81,10 +78,10 @@
pre { pre {
padding: 0; padding: 0;
font-family: $family-monospace; font-family: $core-font-monospace;
> code { > code {
box-shadow: inset 0 0 5px 0 $grey-light; box-shadow: inset 0 0 5px 0 mc('grey', '100');
border-radius: 5px; border-radius: 5px;
} }
...@@ -106,7 +103,7 @@ ...@@ -106,7 +103,7 @@
} }
strong { strong {
color: $grey-dark; color: mc('grey', '700');
} }
.twa { .twa {
...@@ -114,18 +111,18 @@ ...@@ -114,18 +111,18 @@
} }
table thead th { table thead th {
background-color: $blue; background-color: mc('blue', '500');
color: #FFF; color: #FFF;
border-color: #FFF; border-color: #FFF;
border-bottom-color: $blue; border-bottom-color: mc('blue', '500');
border-top-color: $blue; border-top-color: mc('blue', '500');
&:first-child { &:first-child {
border-left-color: $blue; border-left-color: mc('blue', '500');
} }
&:last-child { &:last-child {
border-right-color: $blue; border-right-color: mc('blue', '500');
} }
} }
...@@ -133,58 +130,16 @@ ...@@ -133,58 +130,16 @@
} }
.content a:not(.button):visited { .content a:not(.button):visited {
color: $turquoise; color: mc('teal', '500');
font-weight: 500; font-weight: 500;
} }
code { code {
font-weight: 500; font-weight: 500;
color: $purple; color: mc('purple', '500');
} }
p code { p code {
padding: 2px 5px; padding: 2px 5px;
border-radius: 4px; border-radius: 4px;
}
.modal {
align-items: flex-start;
}
.modal-background {
animation: 0.4s ease fadeIn;
}
.modal-content {
animation: 0.4s ease slideInDown;
}
.card-header {
background-color: $turquoise;
&.is-warning {
background-color: $orange;
}
&.is-danger {
background-color: $red;
}
&.is-info {
background-color: $purple;
}
}
.card-header-title {
color: #FFF;
font-weight: 400;
font-size: 16px;
padding: 10px 20px;
}
.modal-content .card-footer-item {
font-weight: 500;
}
.modal-content .card-footer-item.featured {
animation: flash 4s ease 0 infinite;
} }
\ No newline at end of file
// Roboto
// by Christian Robertson
// Apache 2.0 License
// -> Thin
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Thin.woff') format('woff');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-ThinItalic.woff') format('woff');
font-weight: 100;
font-style: italic;
}
// -> Light
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Light.woff') format('woff');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-LightItalic.woff') format('woff');
font-weight: 300;
font-style: italic;
}
// -> Regular
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-RegularItalic.woff') format('woff');
font-weight: 400;
font-style: italic;
}
// -> Medium
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-MediumItalic.woff') format('woff');
font-weight: 500;
font-style: italic;
}
// -> Bold
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-BoldItalic.woff') format('woff');
font-weight: 700;
font-style: italic;
}
// -> Black
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-Black.woff') format('woff');
font-weight: 900;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-BlackItalic.woff') format('woff');
font-weight: 900;
font-style: italic;
}
\ No newline at end of file
.footer {
background-color: mc('light-blue', '600');
color: #FFF;
text-align: center;
padding: 25px;
}
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
h2.nav-item { h2.nav-item {
font-size: 150%; font-size: 150%;
color: $orange; color: mc('orange', '500');
} }
#notifload { #notifload {
...@@ -26,7 +26,7 @@ h2.nav-item { ...@@ -26,7 +26,7 @@ h2.nav-item {
&::before { &::before {
content: " "; content: " ";
@include spinner($orange,0.5s,24px); @include spinner(mc('orange', '500'),0.5s,24px);
} }
&.active { &.active {
......
.block {
&:not(:last-child) {
margin-bottom: 20px;
}
}
.container {
position: relative;
@include desktop {
margin: 0 auto;
max-width: 960px;
// Modifiers
&.is-fluid {
margin: 0 20px;
max-width: none;
}
}
@include widescreen {
max-width: 1200px;
}
}
.fa {
font-size: 21px;
text-align: center;
vertical-align: top;
}
// Display
$displays: "block" "flex" "inline" "inline-block" "inline-flex";
@each $display in $displays {
.is-#{$display} {
display: #{$display};
}
.is-#{$display}-mobile {
@include mobile {
display: #{$display} !important;
}
}
.is-#{$display}-tablet {
@include tablet {
display: #{$display} !important;
}
}
.is-#{$display}-tablet-only {
@include tablet-only {
display: #{$display} !important;
}
}
.is-#{$display}-touch {
@include touch {
display: #{$display} !important;
}
}
.is-#{$display}-desktop {
@include desktop {
display: #{$display} !important;
}
}
.is-#{$display}-desktop-only {
@include desktop-only {
display: #{$display} !important;
}
}
.is-#{$display}-widescreen {
@include widescreen {
display: #{$display} !important;
}
}
}
// Float
.is-clearfix {
@include clearfix;
}
.is-pulled-left {
float: left;
}
.is-pulled-right {
float: right;
}
// Overflow
.is-clipped {
overflow: hidden !important;
}
// Overlay
.is-overlay {
@include overlay;
}
// Text
.has-text-centered {
text-align: center;
}
.has-text-left {
text-align: left;
}
.has-text-right {
text-align: right;
}
// Visibility
.is-hidden {
display: none !important;
}
.is-hidden-mobile {
@include mobile {
display: none !important;
}
}
.is-hidden-tablet {
@include tablet {
display: none !important;
}
}
.is-hidden-tablet-only {
@include tablet-only {
display: none !important;
}
}
.is-hidden-touch {
@include touch {
display: none !important;
}
}
.is-hidden-desktop {
@include desktop {
display: none !important;
}
}
.is-hidden-desktop-only {
@include desktop-only {
display: none !important;
}
}
.is-hidden-widescreen {
@include widescreen {
display: none !important;
}
}
// Other
.is-disabled {
pointer-events: none;
}
.is-marginless {
margin: 0 !important;
}
.is-unselectable {
@extend .unselectable;
}
// Components
.nav-toggle {
@extend .hamburger;
// Responsiveness
@include tablet {
display: none;
}
}
.nav-item {
align-items: center;
display: flex;
justify-content: center;
padding: 10px;
a {
flex-grow: 1;
}
img {
max-height: 24px;
}
.button + .button {
margin-left: 10px;
}
.tag {
&:first-child {
margin-right: 5px;
}
&:last-child {
margin-left: 5px;
}
}
// Responsiveness
@include mobile {
justify-content: flex-start;
}
}
.nav-item a,
a.nav-item {
color: $text;
&:hover {
color: $link-hover;
}
// Modifiers
&.is-active {
color: $link-active;
}
&.is-tab {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
padding-left: 12px;
padding-right: 12px;
&:hover {
border-bottom: 1px solid $link;
border-top: 1px solid transparent;
}
&.is-active {
border-bottom: 3px solid $link;
border-top: 3px solid transparent;
color: $link;
}
}
}
// Containers
.nav-menu {
// Responsiveness
@include mobile {
background-color: $white;
box-shadow: 0 4px 7px rgba($black, 0.1);
left: 0;
display: none;
right: 0;
top: 100%;
position: absolute;
.nav-item {
border-top: 1px solid rgba($border, 0.5);
padding: 10px;
}
&.is-active {
display: block;
}
}
@include tablet-only {
padding-right: 20px;
}
}
.nav-left {
align-items: stretch;
display: flex;
flex-basis: 0;
flex-grow: 1;
justify-content: flex-start;
overflow: hidden;
overflow-x: auto;
white-space: nowrap;
}
.nav-center {
align-items: stretch;
display: flex;
justify-content: center;
margin-left: auto;
margin-right: auto;
}
.nav-right {
// Responsiveness
@include tablet {
align-items: stretch;
display: flex;
flex-basis: 0;
flex-grow: 1;
justify-content: flex-end;
}
}
// Main container
.nav {
align-items: stretch;
background-color: $white;
display: flex;
min-height: $nav-height;
position: relative;
text-align: center;
z-index: 2;
& > .container {
align-items: stretch;
display: flex;
min-height: $nav-height;
width: 100%;
& > .nav-left {
& > .nav-item:first-child:not(.is-tab) {
padding-left: 0;
}
}
& > .nav-right {
& > .nav-item:last-child:not(.is-tab) {
padding-right: 0;
}
}
}
.container > & {
& > .nav-left {
& > .nav-item:first-child:not(.is-tab) {
padding-left: 0;
}
}
& > .nav-right {
& > .nav-item:last-child:not(.is-tab) {
padding-right: 0;
}
}
}
// Modifiers
&.has-shadow {
box-shadow: 0 2px 3px rgba($black, 0.1);
}
// Responsiveness
@include touch {
& > .container,
.container > & {
& > .nav-left {
& > .nav-item.is-brand:first-child {
padding-left: 20px;
}
}
}
}
}
@mixin arrow($color) {
border: 1px solid $color;
border-right: 0;
border-top: 0;
content: " ";
display: block;
height: 7px;
pointer-events: none;
position: absolute;
transform: rotate(-45deg);
width: 7px;
}
@mixin clearfix {
&:after {
clear: both;
content: " ";
display: table;
}
}
@mixin center($size) {
left: 50%;
margin-left: -($size / 2);
margin-top: -($size / 2);
position: absolute;
top: 50%;
}
@mixin fa($size, $dimensions) {
display: inline-block;
font-size: $size;
height: $dimensions;
line-height: $dimensions;
text-align: center;
vertical-align: top;
width: $dimensions;
}
@mixin overlay($offset: 0) {
bottom: $offset;
left: $offset;
position: absolute;
right: $offset;
top: $offset;
}
@mixin placeholder {
$placeholders: ":-moz" ":-webkit-input" "-moz" "-ms-input";
@each $placeholder in $placeholders {
&:#{$placeholder}-placeholder {
@content;
}
}
}
@mixin replace($background, $width, $height) {
background-color: $background;
background-position: center center;
background-repeat: no-repeat;
background-size: $width $height;
display: block;
height: $height;
outline: none;
overflow: hidden;
text-indent: -290486px;
width: $width;
}
@mixin from($device) {
@media screen and (min-width: $device) {
@content;
}
}
@mixin until($device) {
@media screen and (max-width: $device - 1px) {
@content;
}
}
@mixin mobile {
@media screen and (max-width: $tablet - 1px) {
@content;
}
}
@mixin tablet {
@media screen and (min-width: $tablet) {
@content;
}
}
@mixin tablet-only {
@media screen and (min-width: $tablet) and (max-width: $desktop - 1px) {
@content;
}
}
@mixin touch {
@media screen and (max-width: $desktop - 1px) {
@content;
}
}
@mixin desktop {
@media screen and (min-width: $desktop) {
@content;
}
}
@mixin desktop-only {
@media screen and (min-width: $desktop) and (max-width: $widescreen - 1px) {
@content;
}
}
@mixin widescreen {
@media screen and (min-width: $widescreen) {
@content;
}
}
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
line-height: 1; line-height: 1;
color: $primary; color: mc('blue', '500');
text-align: center; text-align: center;
-webkit-transform: translateY(-50%); -webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%); -ms-transform: translateY(-50%);
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
font-size: 14px; font-size: 14px;
list-style-type: none; list-style-type: none;
background: #fff; background: #fff;
border: 1px solid $primary; border: 1px solid mc('blue', '500');
border-radius: .2em; border-radius: .2em;
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .25); -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .25);
box-shadow: 0 2px 5px rgba(0, 0, 0, .25); box-shadow: 0 2px 5px rgba(0, 0, 0, .25);
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
.context-menu-item.context-menu-hover { .context-menu-item.context-menu-hover {
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
background-color: $primary; background-color: mc('blue', '500');
} }
.context-menu-item.context-menu-disabled { .context-menu-item.context-menu-disabled {
......
@import './layout/_base'; @import 'core-client/scss/core';
@import './layout/_mixins'; @import 'core-client/scss/pages/login';
\ No newline at end of file
@import './libs/animate.min.css';
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 14px;
}
a {
color: #FFF;
transition: color 0.4s ease;
text-decoration: none;
&:hover {
color: #FB8C00;
text-decoration: underline;
}
}
#bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
background-color: #000;
> div {
background-size: cover;
background-position: center center;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
visibility: hidden;
transition: opacity 3s ease, visibility 3s;
animation: bg 30s linear infinite;
&:nth-child(1) {
animation-delay: 10s;
}
&:nth-child(2) {
animation-delay: 20s;
}
}
}
#root {
position: fixed;
top: 15vh;
left: 10vw;
z-index: 2;
color: #FFF;
display: flex;
flex-direction: column;
h1 {
font-size: 4rem;
color: #FFF;
padding: 0;
margin: 0;
animation: headerIntro 3s ease;
}
h2 {
font-size: 1.5rem;
font-weight: normal;
color: rgba(255,255,255,0.7);
padding: 0;
margin: 0 0 25px 0;
animation: headerIntro 3s ease;
}
h3 {
font-size: 1.25rem;
font-weight: normal;
color: #FB8C00;
padding: 0;
margin: 0;
animation: shake 1s ease;
> .fa {
margin-right: 7px;
}
}
h4 {
font-size: 0.8rem;
font-weight: normal;
color: rgba(255,255,255,0.7);
padding: 0;
margin: 0 0 15px 0;
animation: fadeIn 3s ease;
}
form {
display: flex;
flex-direction: column;
}
input[type=text], input[type=password] {
width: 350px;
max-width: 80vw;
border: 1px solid rgba(255,255,255,0.3);
border-radius: 3px;
background-color: rgba(0,0,0,0.2);
padding: 0 15px;
height: 40px;
margin: 0 0 10px 0;
color: #FFF;
font-weight: bold;
font-size: 14px;
transition: all 0.4s ease;
&:focus {
outline: none;
border-color: #FB8C00;
}
}
button {
background-color: #FB8C00;
color: #FFF;
border: 1px solid lighten(#FB8C00, 10%);
border-radius: 3px;
height: 40px;
width: 125px;
padding: 0;
font-weight: bold;
margin: 15px 0 0 0;
transition: all 0.4s ease;
cursor: pointer;
&:focus {
outline: none;
border-color: #FFF;
}
&:hover {
background-color: darken(#FB8C00, 10%);
}
}
#social {
margin-top: 25px;
> span {
display: block;
font-weight: bold;
color: rgba(255,255,255,0.7);
}
button {
margin-right: 5px;
width: auto;
padding: 0 15px;
> i {
margin-right: 10px;
font-size: 16px;
}
&.ms {
background-color: #009688;
border-color: lighten(#009688, 10%);
&:focus {
border-color: #FFF;
}
&:hover {
background-color: darken(#009688, 10%);
}
}
&.google {
background-color: #2196F3;
border-color: lighten(#2196F3, 10%);
&:focus {
border-color: #FFF;
}
&:hover {
background-color: darken(#2196F3, 10%);
}
}
&.facebook {
background-color: #673AB7;
border-color: lighten(#673AB7, 10%);
&:focus {
border-color: #FFF;
}
&:hover {
background-color: darken(#673AB7, 10%);
}
}
}
}
}
#copyright {
display: flex;
align-items: center;
justify-content: flex-start;
position: absolute;
left: 10vw;
bottom: 10vh;
z-index: 2;
color: rgba(255,255,255,0.5);
font-weight: bold;
.icon {
font-size: 1.2rem;
margin: 0 8px;
}
a {
opacity: 0.75;
}
}
@include keyframes(bg) {
0% {
@include prefix(transform, scale(1,1));
visibility: visible;
opacity: 0;
},
5% {
opacity: 0.5;
},
33% {
opacity: 0.5;
},
38% {
@include prefix(transform, scale(1.2, 1.2));
opacity: 0;
},
39% {
visibility: hidden;
}
100% {
visibility: hidden;
opacity: 0;
}
}
@include keyframes(headerIntro) {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
var express = require('express'); var express = require('express');
var router = express.Router(); var router = express.Router();
const Promise = require('bluebird');
/** /**
* Admin * Admin
...@@ -11,7 +12,30 @@ router.get('/', (req, res) => { ...@@ -11,7 +12,30 @@ router.get('/', (req, res) => {
}); });
router.get('/profile', (req, res) => { router.get('/profile', (req, res) => {
res.render('pages/account.pug'); res.render('pages/admin/profile', { adminTab: 'profile' });
});
router.get('/stats', (req, res) => {
Promise.all([
db.Entry.count(),
db.UplFile.count(),
db.User.count()
]).spread((totalEntries, totalUploads, totalUsers) => {
return res.render('pages/admin/stats', {
totalEntries, totalUploads, totalUsers,
adminTab: 'stats'
}) || true;
}).catch((err) => {
throw err;
});
});
router.get('/users', (req, res) => {
res.render('pages/admin/users', { adminTab: 'users' });
});
router.get('/settings', (req, res) => {
res.render('pages/admin/settings', { adminTab: 'settings' });
}); });
module.exports = router; module.exports = router;
\ No newline at end of file
.sidebar {
background-color: #FFF;
}
var gulp = require("gulp"); var gulp = require("gulp");
var watch = require('gulp-watch');
var merge = require('merge-stream'); var merge = require('merge-stream');
var babel = require("gulp-babel"); var babel = require("gulp-babel");
var uglify = require('gulp-uglify'); var uglify = require('gulp-uglify');
...@@ -18,48 +19,59 @@ var include = require("gulp-include"); ...@@ -18,48 +19,59 @@ var include = require("gulp-include");
* @type {Object} * @type {Object}
*/ */
var paths = { var paths = {
scriptlibs: [ scripts: {
'./node_modules/socket.io-client/socket.io.js', combine: [
'./node_modules/jquery/dist/jquery.min.js', './node_modules/socket.io-client/socket.io.js',
'./node_modules/vue/dist/vue.min.js', './node_modules/jquery/dist/jquery.min.js',
'./node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js', './node_modules/vue/dist/vue.min.js',
'./node_modules/jquery-simple-upload/simpleUpload.min.js', './node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js',
'./node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js', './node_modules/jquery-simple-upload/simpleUpload.min.js',
'./node_modules/sticky-js/dist/sticky.min.js', './node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js',
'./node_modules/simplemde/dist/simplemde.min.js', './node_modules/sticky-js/dist/sticky.min.js',
'./node_modules/ace-builds/src-min-noconflict/ace.js', './node_modules/simplemde/dist/simplemde.min.js',
'./node_modules/ace-builds/src-min-noconflict/ext-modelist.js', './node_modules/ace-builds/src-min-noconflict/ace.js',
'./node_modules/ace-builds/src-min-noconflict/mode-markdown.js', './node_modules/ace-builds/src-min-noconflict/ext-modelist.js',
'./node_modules/ace-builds/src-min-noconflict/theme-tomorrow_night.js', './node_modules/ace-builds/src-min-noconflict/mode-markdown.js',
'./node_modules/filesize.js/dist/filesize.min.js', './node_modules/ace-builds/src-min-noconflict/theme-tomorrow_night.js',
'./node_modules/lodash/lodash.min.js' './node_modules/filesize.js/dist/filesize.min.js',
], './node_modules/lodash/lodash.min.js'
scriptlibs_acemodes: [ ],
'./node_modules/ace-builds/src-min-noconflict/mode-*.js', ace: [
'!./node_modules/ace-builds/src-min-noconflict/mode-markdown.js' './node_modules/ace-builds/src-min-noconflict/mode-*.js',
], '!./node_modules/ace-builds/src-min-noconflict/mode-markdown.js'
scriptapps: [ ],
'./client/js/*.js' compile: [
], './client/js/*.js'
scriptapps_watch: [ ],
'./client/js/**/*.js' watch: [
], './client/js/**/*.js'
csslibs: [ ]
'./node_modules/font-awesome/css/font-awesome.min.css', },
'./node_modules/highlight.js/styles/default.css', css: {
'./node_modules/simplemde/dist/simplemde.min.css' combine: [
], './node_modules/font-awesome/css/font-awesome.min.css',
cssapps: [ './node_modules/highlight.js/styles/tomorrow.css',
'./client/scss/*.scss' './node_modules/simplemde/dist/simplemde.min.css'
], ],
cssapps_watch: [ compile: [
'./client/scss/**/*.scss' './client/scss/*.scss'
], ],
includes: [
'../core',
//'./node_modules/requarks-core'
],
watch: [
'./client/scss/**/*.scss',
'../core/core-client/scss/**/*.scss'
]
},
fonts: [ fonts: [
'./node_modules/font-awesome/fonts/*-webfont.*', './node_modules/font-awesome/fonts/*-webfont.*',
'!./node_modules/font-awesome/fonts/*-webfont.svg' '!./node_modules/font-awesome/fonts/*-webfont.svg',
//'../node_modules/requarks-core/core-client/fonts/**/*'
'../core/core-client/fonts/**/*'
], ],
deploypackage: [ deploy: [
'./**/*', './**/*',
'!node_modules', '!node_modules/**', '!node_modules', '!node_modules/**',
'!coverage', '!coverage/**', '!coverage', '!coverage/**',
...@@ -77,7 +89,7 @@ var paths = { ...@@ -77,7 +89,7 @@ var paths = {
/** /**
* TASK - Starts server in development mode * TASK - Starts server in development mode
*/ */
gulp.task('server', ['scripts', 'css'/*, 'fonts'*/], function() { gulp.task('server', ['scripts', 'css', 'fonts'], function() {
nodemon({ nodemon({
script: './server', script: './server',
ignore: ['assets/', 'client/', 'data/', 'repo/', 'tests/'], ignore: ['assets/', 'client/', 'data/', 'repo/', 'tests/'],
...@@ -98,12 +110,12 @@ gulp.task("scripts-libs", function () { ...@@ -98,12 +110,12 @@ gulp.task("scripts-libs", function () {
return merge( return merge(
gulp.src(paths.scriptlibs) gulp.src(paths.scripts.combine)
.pipe(concat('libs.js', {newLine: ';\n'})) .pipe(concat('libs.js', {newLine: ';\n'}))
.pipe(uglify({ mangle: false })) .pipe(uglify({ mangle: false }))
.pipe(gulp.dest("./assets/js")), .pipe(gulp.dest("./assets/js")),
gulp.src(paths.scriptlibs_acemodes) gulp.src(paths.scripts.ace)
.pipe(gulp.dest("./assets/js/ace")) .pipe(gulp.dest("./assets/js/ace"))
); );
...@@ -115,7 +127,7 @@ gulp.task("scripts-libs", function () { ...@@ -115,7 +127,7 @@ gulp.task("scripts-libs", function () {
*/ */
gulp.task("scripts-app", function () { gulp.task("scripts-app", function () {
return gulp.src(paths.scriptapps) return gulp.src(paths.scripts.compile)
.pipe(plumber()) .pipe(plumber())
.pipe(include({ extensions: "js" })) .pipe(include({ extensions: "js" }))
.pipe(babel()) .pipe(babel())
...@@ -134,7 +146,7 @@ gulp.task("css", ['css-libs', 'css-app']); ...@@ -134,7 +146,7 @@ gulp.task("css", ['css-libs', 'css-app']);
* TASK - Combine css libraries * TASK - Combine css libraries
*/ */
gulp.task("css-libs", function () { gulp.task("css-libs", function () {
return gulp.src(paths.csslibs) return gulp.src(paths.css.combine)
.pipe(plumber()) .pipe(plumber())
.pipe(concat('libs.css')) .pipe(concat('libs.css'))
.pipe(cleanCSS({ keepSpecialComments: 0 })) .pipe(cleanCSS({ keepSpecialComments: 0 }))
...@@ -146,9 +158,9 @@ gulp.task("css-libs", function () { ...@@ -146,9 +158,9 @@ gulp.task("css-libs", function () {
* TASK - Combine app css * TASK - Combine app css
*/ */
gulp.task("css-app", function () { gulp.task("css-app", function () {
return gulp.src(paths.cssapps) return gulp.src(paths.css.compile)
.pipe(plumber()) .pipe(plumber())
.pipe(sass()) .pipe(sass.sync({ includePaths: paths.css.includes }))
.pipe(cleanCSS({ keepSpecialComments: 0 })) .pipe(cleanCSS({ keepSpecialComments: 0 }))
.pipe(plumber.stop()) .pipe(plumber.stop())
.pipe(gulp.dest("./assets/css")); .pipe(gulp.dest("./assets/css"));
...@@ -166,8 +178,10 @@ gulp.task("fonts", function () { ...@@ -166,8 +178,10 @@ gulp.task("fonts", function () {
* TASK - Start dev watchers * TASK - Start dev watchers
*/ */
gulp.task('watch', function() { gulp.task('watch', function() {
gulp.watch([paths.scriptapps_watch], ['scripts-app']); return merge(
gulp.watch([paths.cssapps_watch], ['css-app']); watch(paths.scripts.watch, {base: './'}, function() { return gulp.start('scripts-app'); }),
watch(paths.css.watch, {base: './'}, function() { return gulp.start('css-app'); })
);
}); });
/** /**
...@@ -179,11 +193,11 @@ gulp.task('default', ['watch', 'server']); ...@@ -179,11 +193,11 @@ gulp.task('default', ['watch', 'server']);
* TASK - Creates deployment packages * TASK - Creates deployment packages
*/ */
gulp.task('deploy', ['scripts', 'css', 'fonts'], function() { gulp.task('deploy', ['scripts', 'css', 'fonts'], function() {
var zipStream = gulp.src(paths.deploypackage) var zipStream = gulp.src(paths.deploy)
.pipe(zip('requarks-wiki.zip')) .pipe(zip('requarks-wiki.zip'))
.pipe(gulp.dest('dist')); .pipe(gulp.dest('dist'));
var targzStream = gulp.src(paths.deploypackage) var targzStream = gulp.src(paths.deploy)
.pipe(tar('requarks-wiki.tar')) .pipe(tar('requarks-wiki.tar'))
.pipe(gzip()) .pipe(gzip())
.pipe(gulp.dest('dist')); .pipe(gulp.dest('dist'));
......
"use strict";
const LocalStrategy = require('passport-local').Strategy;
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const WindowsLiveStrategy = require('passport-windowslive').Strategy;
const FacebookStrategy = require('passport-facebook').Strategy;
const _ = require('lodash');
module.exports = function(passport, appconfig) {
// Serialization user methods
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
db.User.findById(id).then((user) => {
if(user) {
done(null, user);
} else {
done(new Error('User not found.'), null);
}
return true;
}).catch((err) => {
done(err, null);
});
});
// Local Account
if(appconfig.auth.local && appconfig.auth.local.enabled) {
passport.use('local',
new LocalStrategy({
usernameField : 'email',
passwordField : 'password'
},
(uEmail, uPassword, done) => {
db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
if(user) {
return user.validatePassword(uPassword).then(() => {
return done(null, user) || true;
}).catch((err) => {
return done(err, null);
});
} else {
return done(new Error('Invalid Login'), null);
}
}).catch((err) => {
done(err, null) ;
});
}
));
}
// Google ID
if(appconfig.auth.google && appconfig.auth.google.enabled) {
passport.use('google',
new GoogleStrategy({
clientID: appconfig.auth.google.clientId,
clientSecret: appconfig.auth.google.clientSecret,
callbackURL: appconfig.host + '/login/google/callback'
},
(accessToken, refreshToken, profile, cb) => {
db.User.processProfile(profile).then((user) => {
return cb(null, user) || true;
}).catch((err) => {
return cb(err, null) || true;
});
}
));
}
// Microsoft Accounts
if(appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) {
passport.use('windowslive',
new WindowsLiveStrategy({
clientID: appconfig.auth.microsoft.clientId,
clientSecret: appconfig.auth.microsoft.clientSecret,
callbackURL: appconfig.host + '/login/ms/callback'
},
function(accessToken, refreshToken, profile, cb) {
db.User.processProfile(profile).then((user) => {
return cb(null, user) || true;
}).catch((err) => {
return cb(err, null) || true;
});
}
));
}
// Facebook
if(appconfig.auth.facebook && appconfig.auth.facebook.enabled) {
passport.use('facebook',
new FacebookStrategy({
clientID: appconfig.auth.facebook.clientId,
clientSecret: appconfig.auth.facebook.clientSecret,
callbackURL: appconfig.host + '/login/facebook/callback',
profileFields: ['id', 'displayName', 'email']
},
function(accessToken, refreshToken, profile, cb) {
db.User.processProfile(profile).then((user) => {
return cb(null, user) || true;
}).catch((err) => {
return cb(err, null) || true;
});
}
));
}
// Check for admin access
db.onReady.then(() => {
db.User.count().then((c) => {
if(c < 1) {
winston.info('[' + PROCNAME + '][AUTH] No administrator account found. Creating a new one...');
db.User.hashPassword('admin123').then((pwd) => {
return db.User.create({
provider: 'local',
email: appconfig.admin,
name: "Administrator",
password: pwd,
rights: [{
role: 'admin',
path: '/',
exact: false,
deny: false
}]
});
}).then(() => {
winston.info('[' + PROCNAME + '][AUTH] Administrator account created successfully!');
}).catch((err) => {
winston.error('[' + PROCNAME + '][AUTH] An error occured while creating administrator account:');
winston.error(err);
});
}
});
return true;
});
};
\ No newline at end of file
"use strict";
var fs = require('fs'),
yaml = require('js-yaml'),
_ = require('lodash');
/**
* Load Application Configuration
*
* @param {String} confPath Path to the configuration file
* @return {Object} Application Configuration
*/
module.exports = (confPath) => {
var appconfig = {};
try {
appconfig = yaml.safeLoad(fs.readFileSync(confPath, 'utf8'));
} catch (ex) {
winston.error(ex);
process.exit(1);
}
// Merge with defaults
appconfig = _.defaultsDeep(appconfig, {
title: "Requarks Wiki",
host: "http://localhost",
port: process.env.PORT,
auth: {
local: { enabled: true },
microsoft: { enabled: false },
google: { enabled: false },
facebook: { enabled: false },
},
db: "mongodb://localhost/wiki",
redis: null,
sessionSecret: null,
admin: null
});
// List authentication strategies
appconfig.authStrategies = {
list: _.filter(appconfig.auth, ['enabled', true]),
socialEnabled: (_.chain(appconfig.auth).omit('local').reject({ enabled: false }).value().length > 0)
}
if(appconfig.authStrategies.list.length < 1) {
winston.error(new Error('You must enable at least 1 authentication strategy!'));
process.exit(1);
}
return appconfig;
};
\ No newline at end of file
...@@ -151,7 +151,18 @@ const parseContent = (content) => { ...@@ -151,7 +151,18 @@ const parseContent = (content) => {
let output = mkdown.render(content); let output = mkdown.render(content);
let cr = cheerio.load(output); let cr = cheerio.load(output);
cr('table').addClass('table is-bordered is-striped is-narrow');
//-> Style table headers
//cr('table').addClass('table is-bordered is-striped is-narrow');
//-> Remove links in headers
cr('h1 > a:not(.toc-anchor), h2 > a:not(.toc-anchor), h3 > a:not(.toc-anchor)').each((i, elm) => {
let txtLink = cr(elm).text();
cr(elm).replaceWith(txtLink);
});
output = cr.html(); output = cr.html();
return output; return output;
......
"use strict";
const modb = require('mongoose'),
fs = require("fs"),
path = require("path"),
_ = require('lodash');
/**
* MongoDB module
*
* @param {Object} appconfig Application config
* @return {Object} MongoDB wrapper instance
*/
module.exports = {
/**
* Initialize DB
*
* @param {Object} appconfig The application config
* @return {Object} DB instance
*/
init(appconfig) {
let self = this;
let dbModelsPath = path.resolve(ROOTPATH, 'models');
modb.Promise = require('bluebird');
// Event handlers
modb.connection.on('error', (err) => {
winston.error('[' + PROCNAME + '] Failed to connect to MongoDB instance.');
});
modb.connection.once('open', function() {
winston.log('[' + PROCNAME + '] Connected to MongoDB instance.');
});
// Store connection handle
self.connection = modb.connection;
self.ObjectId = modb.Types.ObjectId;
// Load DB Models
fs
.readdirSync(dbModelsPath)
.filter(function(file) {
return (file.indexOf(".") !== 0);
})
.forEach(function(file) {
let modelName = _.upperFirst(_.camelCase(_.split(file,'.')[0]));
self[modelName] = require(path.join(dbModelsPath, file));
});
// Connect
self.onReady = modb.connect(appconfig.db);
return self;
}
};
\ No newline at end of file
"use strict";
const _ = require('lodash');
/**
* Rights
*/
module.exports = {
check(req, role) {
let rt = [];
let p = _.chain(req.originalUrl).toLower().trim().value();
// Load User Rights
if(_.isArray(req.user.rights)) {
rt = req.user.rights;
}
// Is admin?
if(_.find(rt, { role: 'admin' })) {
return true;
}
// Check specific role on path
let filteredRights = _.filter(rt, (r) => {
if(r.role === role || (r.role === 'write' && role === 'read')) {
if((!r.exact && _.startsWith(p, r.path)) || (r.exact && p === r.path)) {
return true;
}
}
return false;
});
// Check for deny scenario
let isValid = false;
if(filteredRights.length > 1) {
isValid = !_.chain(filteredRights).sortBy((r) => {
return r.path.length + ((r.deny) ? 0.5 : 0);
}).last().get('deny').value();
} else if(filteredRights.length == 1 && filteredRights[0].deny === false) {
isValid = true;
}
// Deny by default
return isValid;
}
};
\ No newline at end of file
"use strict";
var winston = require('winston');
module.exports = (isDebug) => {
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {
level: (isDebug) ? 'debug' : 'info',
prettyPrint: true,
colorize: true,
silent: false,
timestamp: true
});
return winston;
};
\ No newline at end of file
"use strict"; "use strict";
const modb = require('mongoose');
/** /**
* BruteForce schema * BruteForce schema
* *
* @type {<Mongoose.Schema>} * @type {<Mongoose.Schema>}
*/ */
var bruteForceSchema = modb.Schema({ var bruteForceSchema = Mongoose.Schema({
_id: { type: String, index: 1 }, _id: { type: String, index: 1 },
data: { data: {
count: Number, count: Number,
...@@ -17,4 +15,4 @@ var bruteForceSchema = modb.Schema({ ...@@ -17,4 +15,4 @@ var bruteForceSchema = modb.Schema({
expires: { type: Date, index: { expires: '1d' } } expires: { type: Date, index: { expires: '1d' } }
}); });
module.exports = modb.model('Bruteforce', bruteForceSchema); module.exports = Mongoose.model('Bruteforce', bruteForceSchema);
\ No newline at end of file \ No newline at end of file
"use strict"; "use strict";
const modb = require('mongoose'), const Promise = require('bluebird'),
Promise = require('bluebird'),
_ = require('lodash'); _ = require('lodash');
/** /**
...@@ -9,7 +8,7 @@ const modb = require('mongoose'), ...@@ -9,7 +8,7 @@ const modb = require('mongoose'),
* *
* @type {<Mongoose.Schema>} * @type {<Mongoose.Schema>}
*/ */
var entrySchema = modb.Schema({ var entrySchema = Mongoose.Schema({
_id: String, _id: String,
...@@ -51,4 +50,4 @@ entrySchema.index({ ...@@ -51,4 +50,4 @@ entrySchema.index({
name: 'EntriesTextIndex' name: 'EntriesTextIndex'
}); });
module.exports = modb.model('Entry', entrySchema); module.exports = Mongoose.model('Entry', entrySchema);
\ No newline at end of file \ No newline at end of file
"use strict"; "use strict";
const modb = require('mongoose'), const Promise = require('bluebird'),
Promise = require('bluebird'),
_ = require('lodash'); _ = require('lodash');
/** /**
...@@ -9,7 +8,7 @@ const modb = require('mongoose'), ...@@ -9,7 +8,7 @@ const modb = require('mongoose'),
* *
* @type {<Mongoose.Schema>} * @type {<Mongoose.Schema>}
*/ */
var uplFileSchema = modb.Schema({ var uplFileSchema = Mongoose.Schema({
_id: String, _id: String,
...@@ -48,4 +47,4 @@ var uplFileSchema = modb.Schema({ ...@@ -48,4 +47,4 @@ var uplFileSchema = modb.Schema({
timestamps: {} timestamps: {}
}); });
module.exports = modb.model('UplFile', uplFileSchema); module.exports = Mongoose.model('UplFile', uplFileSchema);
\ No newline at end of file \ No newline at end of file
"use strict"; "use strict";
const modb = require('mongoose'), const Promise = require('bluebird'),
Promise = require('bluebird'),
_ = require('lodash'); _ = require('lodash');
/** /**
...@@ -9,7 +8,7 @@ const modb = require('mongoose'), ...@@ -9,7 +8,7 @@ const modb = require('mongoose'),
* *
* @type {<Mongoose.Schema>} * @type {<Mongoose.Schema>}
*/ */
var uplFolderSchema = modb.Schema({ var uplFolderSchema = Mongoose.Schema({
_id: String, _id: String,
...@@ -23,4 +22,4 @@ var uplFolderSchema = modb.Schema({ ...@@ -23,4 +22,4 @@ var uplFolderSchema = modb.Schema({
timestamps: {} timestamps: {}
}); });
module.exports = modb.model('UplFolder', uplFolderSchema); module.exports = Mongoose.model('UplFolder', uplFolderSchema);
\ No newline at end of file \ No newline at end of file
"use strict"; "use strict";
const modb = require('mongoose'), const Promise = require('bluebird'),
Promise = require('bluebird'),
bcrypt = require('bcryptjs-then'), bcrypt = require('bcryptjs-then'),
_ = require('lodash'); _ = require('lodash');
...@@ -10,7 +9,7 @@ const modb = require('mongoose'), ...@@ -10,7 +9,7 @@ const modb = require('mongoose'),
* *
* @type {<Mongoose.Schema>} * @type {<Mongoose.Schema>}
*/ */
var userSchema = modb.Schema({ var userSchema = Mongoose.Schema({
email: { email: {
type: String, type: String,
...@@ -86,4 +85,4 @@ userSchema.methods.validatePassword = function(rawPwd) { ...@@ -86,4 +85,4 @@ userSchema.methods.validatePassword = function(rawPwd) {
}); });
}; };
module.exports = modb.model('User', userSchema); module.exports = Mongoose.model('User', userSchema);
\ No newline at end of file \ No newline at end of file
...@@ -81,7 +81,9 @@ ...@@ -81,7 +81,9 @@
"pug": "^2.0.0-beta6", "pug": "^2.0.0-beta6",
"read-chunk": "^2.0.0", "read-chunk": "^2.0.0",
"remove-markdown": "^0.1.0", "remove-markdown": "^0.1.0",
"requarks-core": "github:requarks/core",
"request": "^2.75.0", "request": "^2.75.0",
"search-index": "^0.9.6",
"serve-favicon": "^2.3.0", "serve-favicon": "^2.3.0",
"sharp": "^0.16.1", "sharp": "^0.16.1",
"simplemde": "^1.11.2", "simplemde": "^1.11.2",
...@@ -111,6 +113,7 @@ ...@@ -111,6 +113,7 @@
"gulp-sass": "^2.3.2", "gulp-sass": "^2.3.2",
"gulp-tar": "^1.9.0", "gulp-tar": "^1.9.0",
"gulp-uglify": "^2.0.0", "gulp-uglify": "^2.0.0",
"gulp-watch": "^4.3.11",
"gulp-zip": "^3.2.0", "gulp-zip": "^3.2.0",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"jquery": "^3.1.1", "jquery": "^3.1.1",
......
...@@ -5,30 +5,30 @@ ...@@ -5,30 +5,30 @@
// Licensed under AGPLv3 // Licensed under AGPLv3
// =========================================== // ===========================================
global.ROOTPATH = __dirname;
global.PROCNAME = 'SERVER'; global.PROCNAME = 'SERVER';
global.ROOTPATH = __dirname;
global.CORE_PATH = ROOTPATH + '/../core/';
global.IS_DEBUG = process.env.NODE_ENV === 'development';
// ---------------------------------------- // ----------------------------------------
// Load Winston // Load Winston
// ---------------------------------------- // ----------------------------------------
const _isDebug = process.env.NODE_ENV === 'development'; global.winston = require(CORE_PATH + 'core-libs/winston')(IS_DEBUG);
global.winston = require('./libs/winston')(_isDebug);
winston.info('[SERVER] Requarks Wiki is initializing...'); winston.info('[SERVER] Requarks Wiki is initializing...');
// ---------------------------------------- // ----------------------------------------
// Load global modules // Load global modules
// ---------------------------------------- // ----------------------------------------
var appconfig = require('./libs/config')('./config.yml'); var appconfig = require(CORE_PATH + 'core-libs/config')('./config.yml');
global.lcdata = require('./libs/local').init(appconfig); global.lcdata = require('./libs/local').init(appconfig);
global.db = require('./libs/mongo').init(appconfig); global.db = require(CORE_PATH + 'core-libs/mongodb').init(appconfig);
global.entries = require('./libs/entries').init(appconfig); global.entries = require('./libs/entries').init(appconfig);
global.git = require('./libs/git').init(appconfig, false); global.git = require('./libs/git').init(appconfig, false);
global.lang = require('i18next'); global.lang = require('i18next');
global.mark = require('./libs/markdown'); global.mark = require('./libs/markdown');
global.upl = require('./libs/uploads').init(appconfig); global.upl = require('./libs/uploads').init(appconfig);
global.rights = require('./libs/rights');
// ---------------------------------------- // ----------------------------------------
// Load modules // Load modules
...@@ -53,7 +53,7 @@ const session = require('express-session'); ...@@ -53,7 +53,7 @@ const session = require('express-session');
const sessionMongoStore = require('connect-mongo')(session); const sessionMongoStore = require('connect-mongo')(session);
const socketio = require('socket.io'); const socketio = require('socket.io');
var mw = autoload(path.join(ROOTPATH, '/middlewares')); var mw = autoload(CORE_PATH + '/core-middlewares');
var ctrl = autoload(path.join(ROOTPATH, '/controllers')); var ctrl = autoload(path.join(ROOTPATH, '/controllers'));
var libInternalAuth = require('./libs/internalAuth'); var libInternalAuth = require('./libs/internalAuth');
...@@ -80,10 +80,12 @@ app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico'))); ...@@ -80,10 +80,12 @@ app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico')));
app.use(express.static(path.join(ROOTPATH, 'assets'))); app.use(express.static(path.join(ROOTPATH, 'assets')));
// ---------------------------------------- // ----------------------------------------
// Session // Passport Authentication
// ---------------------------------------- // ----------------------------------------
const strategies = require('./libs/auth')(passport, appconfig); var strategy = require(CORE_PATH + 'core-libs/auth')(passport, appconfig);
global.rights = require(CORE_PATH + 'core-libs/rights');
var sessionStore = new sessionMongoStore({ var sessionStore = new sessionMongoStore({
mongooseConnection: db.connection, mongooseConnection: db.connection,
touchAfter: 15 touchAfter: 15
...@@ -165,7 +167,7 @@ app.use(function(err, req, res, next) { ...@@ -165,7 +167,7 @@ app.use(function(err, req, res, next) {
res.status(err.status || 500); res.status(err.status || 500);
res.render('error', { res.render('error', {
message: err.message, message: err.message,
error: _isDebug ? err : {} error: IS_DEBUG ? err : {}
}); });
}); });
......
#header-container #header-container
nav.nav.has-shadow.stickyscroll#header nav.nav.stickyscroll#header
.nav-left .nav-left
block rootNavLeft block rootNavLeft
a.nav-item.is-brand(href='/') a.nav-item(href='/')
img(src='/favicons/android-icon-96x96.png', alt='Wiki') img(src='/favicons/android-icon-96x96.png', alt='Wiki')
a.nav-item(href='/') a.nav-item(href='/')
h1.title Wiki h1= appconfig.title
.nav-center .nav-center
block rootNavCenter block rootNavCenter
.nav-item .nav-item
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
span span
span span
span span
.nav-right.nav-menu .nav-right
block rootNavRight block rootNavRight
i.nav-item#notifload i.nav-item#notifload
......
...@@ -28,7 +28,7 @@ html ...@@ -28,7 +28,7 @@ html
block head block head
body body
#root #root.has-stickynav
include ./common/header.pug include ./common/header.pug
include ./common/alerts.pug include ./common/alerts.pug
main main
......
extends ../../layout.pug
block rootNavCenter
block rootNavRight
i.nav-item#notifload
span.nav-item
a.button.is-dark.is-outlined.btn-edit-discard(href='/')
span.icon
i.fa.fa-home
span Home
block content
#page-type-account
section.hero.is-dark
.hero-body
.container
h1.title Account
h2.subtitle Manage your settings and site configuration
nav.nav.has-shadow
.container
.nav-left
a.nav-item.is-tab(href='/admin/profile', class={'is-active': adminTab === 'profile'}) My Profile
a.nav-item.is-tab(href='/admin/stats', class={'is-active': adminTab === 'stats'}) Stats
a.nav-item.is-tab(href='/admin/users', class={'is-active': adminTab === 'users'}) Users
a.nav-item.is-tab(href='/admin/settings', class={'is-active': adminTab === 'settings'}) Site Settings
a.nav-item.is-tab(href='/logout') Logout
block adminContent
\ No newline at end of file
extends ../layout.pug extends ./_layout.pug
block rootNavCenter block adminContent
section.section
.container
block rootNavRight .columns
i.nav-item#notifload .column.is-two-thirds
span.nav-item label.label Email
a.button.is-dark.is-outlined.btn-edit-discard(href='/') p.control.has-icon.has-icon-right
span.icon input.input(type='email', placeholder='Email', value=user.email, disabled=(user.provider !== 'local'))
i.fa.fa-home i.fa.fa-envelope
span Home if user.provider == 'local'
label.label Password
block content
#page-type-account
section.hero.is-dark
.hero-body
.container
h1.title Account
h2.subtitle Manage your settings and site configuration
nav.nav.has-shadow
.container
.nav-left
a.nav-item.is-tab.is-active My Profile
a.nav-item.is-tab Stats
a.nav-item.is-tab Users
a.nav-item.is-tab Site Settings
a.nav-item.is-tab(href='/logout') Logout
section.section
.container
.columns
.column.is-two-thirds
label.label Email
p.control.has-icon.has-icon-right p.control.has-icon.has-icon-right
input.input(type='email', placeholder='Email', value=user.email, disabled=(user.provider !== 'local')) input.input(type='password', placeholder='Password', value='********')
i.fa.fa-envelope i.fa.fa-lock
if user.provider == 'local' label.label Verify Password
label.label Password
p.control.has-icon.has-icon-right
input.input(type='password', placeholder='Password', value='********')
i.fa.fa-lock
label.label Verify Password
p.control.has-icon.has-icon-right
input.input(type='password', placeholder='Password', value='********')
i.fa.fa-lock
label.label Display Name
p.control.has-icon.has-icon-right p.control.has-icon.has-icon-right
input.input(type='text', placeholder='John Smith', value=user.name) input.input(type='password', placeholder='Password', value='********')
i.fa.fa-user i.fa.fa-lock
.column label.label Display Name
label.label Provider p.control.has-icon.has-icon-right
p.control.account-profile-provider input.input(type='text', placeholder='John Smith', value=user.name)
case user.provider i.fa.fa-user
when 'local': i.fa.fa-database .column
when 'windowslive': i.fa.fa-windows.is-blue label.label Provider
when 'google': i.fa.fa-google.is-blue p.control.account-profile-provider
when 'facebook': i.fa.fa-facebook.is-purple case user.provider
default: i.fa.fa-question-circle when 'local': i.fa.fa-database
= t('auth:providers.' + user.provider) when 'windowslive': i.fa.fa-windows.is-blue
label.label Member since when 'google': i.fa.fa-google.is-blue
p.control= userMoment(user.createdAt).format('LL') when 'facebook': i.fa.fa-facebook.is-purple
label.label Last Profile Update default: i.fa.fa-question-circle
p.control= userMoment(user.updatedAt).format('LL') = t('auth:providers.' + user.provider)
section.section label.label Member since
.container p.control= userMoment(user.createdAt).format('LL')
p.control label.label Last Profile Update
button.button.is-success p.control= userMoment(user.updatedAt).format('LL')
| Save Changes section.section
\ No newline at end of file .container
p.control
button.button.is-success
| Save Changes
\ No newline at end of file
extends ./_layout.pug
block adminContent
section.section
.container
label.label Coming soon
\ No newline at end of file
extends ./_layout.pug
block adminContent
section.section
.container
label.label Entries
p.control= totalEntries
label.label Uploads
p.control= totalUploads
label.label Users
p.control= totalUsers
\ No newline at end of file
extends ./_layout.pug
block adminContent
section.section
.container
.columns
.column.is-three-quarters
label.label Coming soon
.column
p.control
button.button.is-info
| Create Local User
p.control
button.button.is-info
| Authorize Social User
\ No newline at end of file
...@@ -6,13 +6,11 @@ block rootNavCenter ...@@ -6,13 +6,11 @@ block rootNavCenter
block rootNavRight block rootNavRight
i.nav-item#notifload i.nav-item#notifload
span.nav-item span.nav-item
a.button.is-warning.is-outlined.btn-edit-discard a.button.is-orange.is-outlined.btn-edit-discard
span.icon i.fa.fa-times
i.fa.fa-times
span Discard span Discard
a.button.is-success.btn-edit-save a.button.is-green.btn-edit-save
span.icon i.fa.fa-check
i.fa.fa-check
span Save Changes span Save Changes
block content block content
......
...@@ -10,13 +10,11 @@ block rootNavRight ...@@ -10,13 +10,11 @@ block rootNavRight
a.nav-item(href='/' + pageData.meta.path) a.nav-item(href='/' + pageData.meta.path)
| Normal View | Normal View
span.nav-item span.nav-item
a.button(href='/edit/' + pageData.meta.path) a.button.is-orange(href='/edit/' + pageData.meta.path)
span.icon i.fa.fa-edit
i.fa.fa-edit
span Edit span Edit
a.button.is-primary.btn-create-prompt a.button.is-blue.btn-create-prompt
span.icon i.fa.fa-plus
i.fa.fa-plus
span Create span Create
block content block content
......
...@@ -15,51 +15,55 @@ block rootNavRight ...@@ -15,51 +15,55 @@ block rootNavRight
a.nav-item(href='/source/' + pageData.meta.path) a.nav-item(href='/source/' + pageData.meta.path)
| Source | Source
span.nav-item span.nav-item
a.button(href='/edit/' + pageData.meta.path) a.button.is-orange.is-outlined(href='/edit/' + pageData.meta.path)
span.icon i.fa.fa-edit
i.fa.fa-edit
span Edit span Edit
a.button.is-primary.btn-create-prompt a.button.is-light-blue.btn-create-prompt
span.icon i.fa.fa-plus
i.fa.fa-plus
span Create span Create
block content block content
#page-type-view(data-entrypath=pageData.meta.path) #page-type-view(data-entrypath=pageData.meta.path)
section.section .container.is-fluid
.container.is-fluid .columns.is-gapless
.columns
.column.is-narrow.sd-menus.is-hidden-touch .column.is-narrow.is-hidden-touch.sidebar
.box aside
aside.menu(style= { 'min-width': '200px' }) .sidebar-label
p.menu-label i.icon-th-small
| Navigation span Navigation
ul.menu-list ul.sidebar-menu
li li
a(href='/') Home a(href='/')
if pageData.parent i.icon-home
li span Home
a(href='/' + pageData.parent.path)= pageData.parent.title if pageData.parent
li li
a(href='/admin') Account a(href='/' + pageData.parent.path)
.box.stickyscroll(data-margin-top=70) i.icon-reply
aside.menu(style= { 'min-width': '200px' }) span= pageData.parent.title
p.menu-label li
| Contents a(href='/admin')
ul.menu-list i.icon-head
a(href='#root', title='Start') Start span Account
+tocMenu(pageData.tree) aside.stickyscroll(data-margin-top=40)
.sidebar-label
i.icon-th-list
span Contents
ul.sidebar-menu
li: a(href='#root', title='Start') Start
+tocMenu(pageData.tree)
.column .column
.hero
h1.title#title= pageData.meta.title h1.title#title= pageData.meta.title
if pageData.meta.subtitle if pageData.meta.subtitle
h2.subtitle= pageData.meta.subtitle h2.subtitle= pageData.meta.subtitle
.content.mkcontent .content.mkcontent
!= pageData.html != pageData.html
include ../modals/create.pug include ../modals/create.pug
include ../modals/move.pug include ../modals/move.pug
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment