Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f9a39c330 | ||
|
|
633ccf427c | ||
|
|
51e4608c19 | ||
|
|
612e620ffc | ||
|
|
642076a231 | ||
|
|
f63639782c | ||
|
|
02615088ff | ||
|
|
5aa3bc86eb | ||
|
|
d5769d56c1 | ||
|
|
8eb0bc147c | ||
|
|
96589a2658 | ||
|
|
34e39edcda | ||
|
|
6d00a8e3aa | ||
|
|
c29b3a7a25 | ||
|
|
a99bf15332 | ||
|
|
7074800ecc | ||
|
|
80fb09d941 | ||
|
|
afabc25037 | ||
|
|
c9e7a3f40a | ||
|
|
4d82106aff | ||
|
|
4c0e261a8e | ||
|
|
9e3935b3b2 | ||
|
|
e4f71fe402 | ||
|
|
06c71f4e65 | ||
|
|
9fcf67d667 | ||
|
|
d1318daaca | ||
|
|
87a0c577bb | ||
|
|
bcc81e1ad8 | ||
|
|
1f8f3b3a36 | ||
|
|
610b61831d | ||
|
|
cf0b394b05 | ||
|
|
a36b11f07d | ||
|
|
93c9ce0cad | ||
|
|
af88db42b2 | ||
|
|
0c6ccdc0a1 | ||
|
|
6d3f8171e5 | ||
|
|
3f1c570e84 | ||
|
|
cd88ae264e | ||
|
|
b2abcae319 | ||
|
|
41a5c675bf | ||
|
|
ac9f896a22 | ||
|
|
36d57914b2 | ||
|
|
800ba5dd0d | ||
|
|
a793f7b3b4 | ||
|
|
0d6dfb8319 |
@@ -3,14 +3,17 @@ stages:
|
|||||||
- go-fmt
|
- go-fmt
|
||||||
- go-test
|
- go-test
|
||||||
- build-src
|
- build-src
|
||||||
|
- aws-upload-tags
|
||||||
- build-docker
|
- build-docker
|
||||||
- docker-registry
|
- docker-registry-master
|
||||||
|
- docker-registry-tags
|
||||||
|
|
||||||
check-dco:
|
check-dco:
|
||||||
stage: check-dco
|
stage: check-dco
|
||||||
image: debian:buster
|
image: debian:buster
|
||||||
except:
|
except:
|
||||||
- master
|
- master
|
||||||
|
- tags
|
||||||
script:
|
script:
|
||||||
- apt update
|
- apt update
|
||||||
- apt install -y curl git jq
|
- apt install -y curl git jq
|
||||||
@@ -19,21 +22,37 @@ check-dco:
|
|||||||
build-src:
|
build-src:
|
||||||
stage: build-src
|
stage: build-src
|
||||||
image: debian:buster
|
image: debian:buster
|
||||||
variables:
|
|
||||||
GOPATH: $CI_PROJECT_DIR
|
|
||||||
except:
|
except:
|
||||||
- master
|
- master
|
||||||
|
- tags
|
||||||
|
before_script:
|
||||||
|
- bash $CI_PROJECT_DIR/scripts/gitlab-ci-build-prescript
|
||||||
script:
|
script:
|
||||||
- apt update
|
- export GOPATH=/go
|
||||||
- apt install -y curl gnupg git make golang
|
- export PATH=$PATH:/go/bin
|
||||||
- curl -sL https://deb.nodesource.com/setup_10.x | bash -
|
- cd /go/src/$CI_PROJECT_NAME
|
||||||
- apt update
|
|
||||||
- apt install -y nodejs
|
|
||||||
- npm install -g html-minifier@3.5.7 uglify-js@3.4.1 sass@1.5.1
|
|
||||||
- mkdir -p src/gitlab.com/commento && cd src/gitlab.com/commento && ln -s $CI_PROJECT_DIR && cd $CI_PROJECT_NAME
|
|
||||||
- make devel
|
- make devel
|
||||||
- make prod
|
- make prod
|
||||||
|
|
||||||
|
aws-upload-tags:
|
||||||
|
stage: aws-upload-tags
|
||||||
|
image: debian:buster
|
||||||
|
environment: aws-upload-tags
|
||||||
|
variables:
|
||||||
|
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
|
||||||
|
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
|
before_script:
|
||||||
|
- bash $CI_PROJECT_DIR/scripts/gitlab-ci-build-prescript
|
||||||
|
script:
|
||||||
|
- export GOPATH=/go
|
||||||
|
- export PATH=$PATH:/go/bin
|
||||||
|
- cd /go/src/$CI_PROJECT_NAME
|
||||||
|
- make prod
|
||||||
|
- cd build/prod && tar -zcvf /commento-linux-amd64-$(git describe --tags).tgz .
|
||||||
|
- aws s3 cp /commento-linux-amd64-$(git describe --tags).tgz s3://commento-release/
|
||||||
|
|
||||||
build-docker:
|
build-docker:
|
||||||
stage: build-docker
|
stage: build-docker
|
||||||
image: docker:stable
|
image: docker:stable
|
||||||
@@ -41,8 +60,9 @@ build-docker:
|
|||||||
- docker:dind
|
- docker:dind
|
||||||
except:
|
except:
|
||||||
- master
|
- master
|
||||||
|
- tags
|
||||||
script:
|
script:
|
||||||
- docker build -t commento-ce .
|
- docker build -t commento .
|
||||||
|
|
||||||
go-test:
|
go-test:
|
||||||
stage: go-test
|
stage: go-test
|
||||||
@@ -54,11 +74,17 @@ go-test:
|
|||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
POSTGRES_DB: commento_test
|
POSTGRES_DB: commento_test
|
||||||
COMMENTO_POSTGRES: postgres://postgres:postgres@postgres/commento_test?sslmode=disable
|
COMMENTO_POSTGRES: postgres://postgres:postgres@postgres/commento_test?sslmode=disable
|
||||||
GOPATH: $CI_PROJECT_DIR
|
|
||||||
except:
|
except:
|
||||||
- master
|
- master
|
||||||
|
- tags
|
||||||
|
before_script:
|
||||||
|
- mkdir -p /go/src /go/bin /go/pkg
|
||||||
|
- export GOPATH=/go
|
||||||
|
- export PATH=$PATH:/go/bin
|
||||||
|
- curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||||
|
- ln -s $CI_PROJECT_DIR /go/src/$CI_PROJECT_NAME
|
||||||
script:
|
script:
|
||||||
- mkdir -p src/gitlab.com/commento && cd src/gitlab.com/commento && ln -s $CI_PROJECT_DIR && cd $CI_PROJECT_NAME
|
- cd /go/src/$CI_PROJECT_NAME
|
||||||
- make test
|
- make test
|
||||||
|
|
||||||
go-fmt:
|
go-fmt:
|
||||||
@@ -66,20 +92,35 @@ go-fmt:
|
|||||||
image: golang:1.10.2
|
image: golang:1.10.2
|
||||||
except:
|
except:
|
||||||
- master
|
- master
|
||||||
|
- tags
|
||||||
script:
|
script:
|
||||||
- cd api
|
- cd api
|
||||||
- test -z $(go fmt)
|
- test -z $(go fmt)
|
||||||
|
|
||||||
docker-registry:
|
docker-registry-master:
|
||||||
stage: docker-registry
|
stage: docker-registry-master
|
||||||
image: docker:stable
|
image: docker:stable
|
||||||
services:
|
services:
|
||||||
- docker:dind
|
- docker:dind
|
||||||
only:
|
only:
|
||||||
- master@commento/commento-ce
|
- master@commento/commento
|
||||||
before_script:
|
before_script:
|
||||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
|
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
|
||||||
script:
|
script:
|
||||||
- docker pull registry.gitlab.com/commento/commento-ce:latest || true
|
- docker pull registry.gitlab.com/commento/commento:latest || true
|
||||||
- docker build --cache-from registry.gitlab.com/commento/commento-ce:latest --tag registry.gitlab.com/commento/commento-ce:latest .
|
- docker build --cache-from registry.gitlab.com/commento/commento:latest --tag registry.gitlab.com/commento/commento:latest .
|
||||||
- docker push registry.gitlab.com/commento/commento-ce:latest
|
- docker push registry.gitlab.com/commento/commento:latest
|
||||||
|
|
||||||
|
docker-registry-tags:
|
||||||
|
stage: docker-registry-tags
|
||||||
|
image: docker:stable
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
|
before_script:
|
||||||
|
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
|
||||||
|
script:
|
||||||
|
- apk add git
|
||||||
|
- docker build --tag registry.gitlab.com/commento/commento:$(git describe --tags) .
|
||||||
|
- docker push registry.gitlab.com/commento/commento:$(git describe --tags)
|
||||||
|
|||||||
37
Dockerfile
37
Dockerfile
@@ -1,10 +1,11 @@
|
|||||||
# backend build (api server)
|
# backend build (api server)
|
||||||
FROM golang:1.10.2-alpine AS api-build
|
FROM golang:1.10.2-alpine AS api-build
|
||||||
|
|
||||||
COPY ./api /go/src/commento-ce/api
|
COPY ./api /go/src/commento/api
|
||||||
WORKDIR /go/src/commento-ce/api
|
WORKDIR /go/src/commento/api
|
||||||
|
|
||||||
RUN apk update && apk add bash make git
|
RUN apk update && apk add bash make git curl
|
||||||
|
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||||
|
|
||||||
RUN make prod -j$(($(nproc) + 1))
|
RUN make prod -j$(($(nproc) + 1))
|
||||||
|
|
||||||
@@ -12,8 +13,8 @@ RUN make prod -j$(($(nproc) + 1))
|
|||||||
# frontend build (html, js, css, images)
|
# frontend build (html, js, css, images)
|
||||||
FROM node:10.3.0-alpine AS frontend-build
|
FROM node:10.3.0-alpine AS frontend-build
|
||||||
|
|
||||||
COPY ./frontend /commento-ce/frontend/
|
COPY ./frontend /commento/frontend/
|
||||||
WORKDIR /commento-ce/frontend/
|
WORKDIR /commento/frontend/
|
||||||
|
|
||||||
RUN apk update && apk add bash make
|
RUN apk update && apk add bash make
|
||||||
RUN npm install -g html-minifier@3.5.7 uglify-js@3.4.1 sass@1.5.1
|
RUN npm install -g html-minifier@3.5.7 uglify-js@3.4.1 sass@1.5.1
|
||||||
@@ -24,8 +25,8 @@ RUN make prod -j$(($(nproc) + 1))
|
|||||||
# templates build
|
# templates build
|
||||||
FROM alpine:3.7 AS templates-build
|
FROM alpine:3.7 AS templates-build
|
||||||
|
|
||||||
COPY ./templates /commento-ce/templates
|
COPY ./templates /commento/templates
|
||||||
WORKDIR /commento-ce/templates
|
WORKDIR /commento/templates
|
||||||
|
|
||||||
RUN apk update && apk add bash make
|
RUN apk update && apk add bash make
|
||||||
|
|
||||||
@@ -35,8 +36,8 @@ RUN make prod -j$(($(nproc) + 1))
|
|||||||
# db build
|
# db build
|
||||||
FROM alpine:3.7 AS db-build
|
FROM alpine:3.7 AS db-build
|
||||||
|
|
||||||
COPY ./db /commento-ce/db
|
COPY ./db /commento/db
|
||||||
WORKDIR /commento-ce/db
|
WORKDIR /commento/db
|
||||||
|
|
||||||
RUN apk update && apk add bash make
|
RUN apk update && apk add bash make
|
||||||
|
|
||||||
@@ -46,19 +47,19 @@ RUN make prod -j$(($(nproc) + 1))
|
|||||||
# final image
|
# final image
|
||||||
FROM alpine:3.7
|
FROM alpine:3.7
|
||||||
|
|
||||||
COPY --from=api-build /go/src/commento-ce/api/build/prod/commento-ce /commento-ce/commento-ce
|
COPY --from=api-build /go/src/commento/api/build/prod/commento /commento/commento
|
||||||
COPY --from=frontend-build /commento-ce/frontend/build/prod/*.html /commento-ce/
|
COPY --from=frontend-build /commento/frontend/build/prod/*.html /commento/
|
||||||
COPY --from=frontend-build /commento-ce/frontend/build/prod/css/*.css /commento-ce/css/
|
COPY --from=frontend-build /commento/frontend/build/prod/css/*.css /commento/css/
|
||||||
COPY --from=frontend-build /commento-ce/frontend/build/prod/js/*.js /commento-ce/js/
|
COPY --from=frontend-build /commento/frontend/build/prod/js/*.js /commento/js/
|
||||||
COPY --from=frontend-build /commento-ce/frontend/build/prod/images/* /commento-ce/images/
|
COPY --from=frontend-build /commento/frontend/build/prod/images/* /commento/images/
|
||||||
COPY --from=templates-build /commento-ce/templates/build/prod/templates/ /commento-ce/templates/
|
COPY --from=templates-build /commento/templates/build/prod/templates/ /commento/templates/
|
||||||
COPY --from=db-build /commento-ce/db/build/prod/db/ /commento-ce/db/
|
COPY --from=db-build /commento/db/build/prod/db/ /commento/db/
|
||||||
|
|
||||||
RUN apk update && apk add ca-certificates --no-cache
|
RUN apk update && apk add ca-certificates --no-cache
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
WORKDIR /commento-ce/
|
WORKDIR /commento/
|
||||||
|
|
||||||
ENV COMMENTO_BIND_ADDRESS="0.0.0.0"
|
ENV COMMENTO_BIND_ADDRESS="0.0.0.0"
|
||||||
ENTRYPOINT ["/commento-ce/commento-ce"]
|
ENTRYPOINT ["/commento/commento"]
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -38,6 +38,16 @@ Commento is possible only because of its community. If this is your first contri
|
|||||||
|
|
||||||
Help will always be given to those who ask for it. We use IRC for chat to collaborate with other developers. You're invited to [hang out with us](https://irc.commento.io) in the `#commento-dev` channel on freenode if you want to contribute to Commento!
|
Help will always be given to those who ask for it. We use IRC for chat to collaborate with other developers. You're invited to [hang out with us](https://irc.commento.io) in the `#commento-dev` channel on freenode if you want to contribute to Commento!
|
||||||
|
|
||||||
|
### Sponsors
|
||||||
|
|
||||||
|
Commento CE development is sponsored by [Mozilla](https://mozilla.org) and [DigitalOcean](https://www.digitalocean.com/) independently.
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.mozilla.org/en-US/"><img src="https://user-images.githubusercontent.com/7521600/32265838-d05b2d08-bf0a-11e7-92e1-2cb183eae616.png" title="Mozilla" height="40"></a>
|
||||||
|
|
||||||
|
<a href="https://www.digitalocean.com"><img src="https://user-images.githubusercontent.com/7521600/32265839-d093c7da-bf0a-11e7-8d99-96a940041d06.png" title="DigitalOcean" height="40"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
#### License
|
#### License
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
9
Gopkg.lock → api/Gopkg.lock
generated
9
Gopkg.lock → api/Gopkg.lock
generated
@@ -9,6 +9,14 @@
|
|||||||
revision = "64a2037ec6be8a4b0c1d1f706ed35b428b989239"
|
revision = "64a2037ec6be8a4b0c1d1f706ed35b428b989239"
|
||||||
version = "v0.26.0"
|
version = "v0.26.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
digest = "1:9769b231d8f5ff406a012aa7f293e45ed69d11617832a1c3c7b8c6ce1558a2a1"
|
||||||
|
name = "github.com/adtac/go-akismet"
|
||||||
|
packages = ["akismet"]
|
||||||
|
pruneopts = "UT"
|
||||||
|
revision = "0ca9e1023047c869ecd4bd3c20780511597a4a77"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:15042ad3498153684d09f393bbaec6b216c8eec6d61f63dff711de7d64ed8861"
|
digest = "1:15042ad3498153684d09f393bbaec6b216c8eec6d61f63dff711de7d64ed8861"
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
@@ -143,6 +151,7 @@
|
|||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
input-imports = [
|
input-imports = [
|
||||||
|
"github.com/adtac/go-akismet/akismet",
|
||||||
"github.com/gorilla/handlers",
|
"github.com/gorilla/handlers",
|
||||||
"github.com/gorilla/mux",
|
"github.com/gorilla/mux",
|
||||||
"github.com/lib/pq",
|
"github.com/lib/pq",
|
||||||
10
api/Makefile
10
api/Makefile
@@ -7,9 +7,9 @@ PROD_BUILD_DIR = $(BUILD_DIR)/prod
|
|||||||
GO_SRC_DIR = .
|
GO_SRC_DIR = .
|
||||||
GO_SRC_FILES = $(wildcard $(GO_SRC_DIR)/*.go)
|
GO_SRC_FILES = $(wildcard $(GO_SRC_DIR)/*.go)
|
||||||
GO_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)
|
GO_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)
|
||||||
GO_DEVEL_BUILD_BINARY = $(GO_DEVEL_BUILD_DIR)/commento-ce
|
GO_DEVEL_BUILD_BINARY = $(GO_DEVEL_BUILD_DIR)/commento
|
||||||
GO_PROD_BUILD_DIR = $(PROD_BUILD_DIR)
|
GO_PROD_BUILD_DIR = $(PROD_BUILD_DIR)
|
||||||
GO_PROD_BUILD_BINARY = $(GO_PROD_BUILD_DIR)/commento-ce
|
GO_PROD_BUILD_BINARY = $(GO_PROD_BUILD_DIR)/commento
|
||||||
|
|
||||||
devel: devel-go
|
devel: devel-go
|
||||||
|
|
||||||
@@ -25,15 +25,15 @@ clean:
|
|||||||
# later down the line).
|
# later down the line).
|
||||||
|
|
||||||
devel-go:
|
devel-go:
|
||||||
go get -v .
|
dep ensure
|
||||||
go build -i -v -o $(GO_DEVEL_BUILD_BINARY)
|
go build -i -v -o $(GO_DEVEL_BUILD_BINARY)
|
||||||
|
|
||||||
prod-go:
|
prod-go:
|
||||||
go get -v .
|
dep ensure
|
||||||
go build -i -v -o $(GO_PROD_BUILD_BINARY)
|
go build -i -v -o $(GO_PROD_BUILD_BINARY)
|
||||||
|
|
||||||
test-go:
|
test-go:
|
||||||
go get -v .
|
dep ensure
|
||||||
go test -v .
|
go test -v .
|
||||||
|
|
||||||
$(shell mkdir -p $(GO_DEVEL_BUILD_DIR) $(GO_PROD_BUILD_DIR))
|
$(shell mkdir -p $(GO_DEVEL_BUILD_DIR) $(GO_PROD_BUILD_DIR))
|
||||||
|
|||||||
31
api/akismet.go
Normal file
31
api/akismet.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/adtac/go-akismet/akismet"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isSpam(domain string, userIp string, userAgent string, name string, email string, url string, markdown string) bool {
|
||||||
|
akismetKey := os.Getenv("AKISMET_KEY")
|
||||||
|
if akismetKey == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := akismet.Check(&akismet.Comment{
|
||||||
|
Blog: domain,
|
||||||
|
UserIP: userIp,
|
||||||
|
UserAgent: userAgent,
|
||||||
|
CommentType: "comment",
|
||||||
|
CommentAuthor: name,
|
||||||
|
CommentAuthorEmail: email,
|
||||||
|
CommentAuthorURL: url,
|
||||||
|
CommentContent: markdown,
|
||||||
|
}, akismetKey)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error: cannot validate commenet using Akismet: %v", err)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
@@ -89,8 +89,12 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
var state string
|
var state string
|
||||||
|
|
||||||
if *x.CommenterToken == "anonymous" {
|
if *x.CommenterToken == "anonymous" {
|
||||||
state = "unapproved"
|
|
||||||
commenterHex = "anonymous"
|
commenterHex = "anonymous"
|
||||||
|
if isSpam(*x.Domain, getIp(r), getUserAgent(r), "Anonymous", "", "", *x.Markdown) {
|
||||||
|
state = "flagged"
|
||||||
|
} else {
|
||||||
|
state = "unapproved"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c, err := commenterGetByCommenterToken(*x.CommenterToken)
|
c, err := commenterGetByCommenterToken(*x.CommenterToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -111,6 +115,9 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
if isModerator {
|
if isModerator {
|
||||||
state = "approved"
|
state = "approved"
|
||||||
|
} else {
|
||||||
|
if isSpam(*x.Domain, getIp(r), getUserAgent(r), c.Name, c.Email, c.Link, *x.Markdown) {
|
||||||
|
state = "flagged"
|
||||||
} else {
|
} else {
|
||||||
if d.RequireModeration {
|
if d.RequireModeration {
|
||||||
state = "unapproved"
|
state = "unapproved"
|
||||||
@@ -119,6 +126,7 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
commentHex, err := commentNew(commenterHex, domain, path, *x.ParentHex, *x.Markdown, state, time.Now().UTC())
|
commentHex, err := commentNew(commenterHex, domain, path, *x.ParentHex, *x.Markdown, state, time.Now().UTC())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -126,5 +134,5 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyMarshal(w, response{"success": true, "commentHex": commentHex, "approved": state == "approved"})
|
bodyMarshal(w, response{"success": true, "commentHex": commentHex, "state": state})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ func configParse() error {
|
|||||||
"SMTP_PORT": "",
|
"SMTP_PORT": "",
|
||||||
"SMTP_FROM_ADDRESS": "",
|
"SMTP_FROM_ADDRESS": "",
|
||||||
|
|
||||||
|
"AKISMET_KEY": "",
|
||||||
|
|
||||||
"GOOGLE_KEY": "",
|
"GOOGLE_KEY": "",
|
||||||
"GOOGLE_SECRET": "",
|
"GOOGLE_SECRET": "",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
var edition = "ce"
|
var version = "v1.4.0"
|
||||||
var version = "v1.1.0"
|
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ func domainDelete(domain string) error {
|
|||||||
return errorInternal
|
return errorInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statement = `
|
||||||
|
DELETE FROM pages
|
||||||
|
WHERE pages.domain = $1;
|
||||||
|
`
|
||||||
|
_, err = db.Exec(statement, domain)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf(statement, domain)
|
||||||
|
return errorInternal
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ func ownerGetByOwnerToken(ownerToken string) (owner, error) {
|
|||||||
statement := `
|
statement := `
|
||||||
SELECT ownerHex, email, name, confirmedEmail, joinDate
|
SELECT ownerHex, email, name, confirmedEmail, joinDate
|
||||||
FROM owners
|
FROM owners
|
||||||
WHERE email IN (
|
WHERE ownerHex IN (
|
||||||
SELECT email FROM ownerSessions
|
SELECT ownerHex FROM ownerSessions
|
||||||
WHERE ownerToken = $1
|
WHERE ownerToken = $1
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ type page struct {
|
|||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
IsLocked bool `json:"isLocked"`
|
IsLocked bool `json:"isLocked"`
|
||||||
CommentCount int `json:"commentCount"`
|
CommentCount int `json:"commentCount"`
|
||||||
|
StickyCommentHex string `json:"stickyCommentHex"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,20 +11,21 @@ func pageGet(domain string, path string) (page, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
statement := `
|
statement := `
|
||||||
SELECT isLocked, commentCount
|
SELECT isLocked, commentCount, stickyCommentHex
|
||||||
FROM pages
|
FROM pages
|
||||||
WHERE domain=$1 AND path=$2;
|
WHERE domain=$1 AND path=$2;
|
||||||
`
|
`
|
||||||
row := db.QueryRow(statement, domain, path)
|
row := db.QueryRow(statement, domain, path)
|
||||||
|
|
||||||
p := page{Domain: domain, Path: path}
|
p := page{Domain: domain, Path: path}
|
||||||
if err := row.Scan(&p.IsLocked, &p.CommentCount); err != nil {
|
if err := row.Scan(&p.IsLocked, &p.CommentCount, &p.StickyCommentHex); err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
// If there haven't been any comments, there won't be a record for this
|
// If there haven't been any comments, there won't be a record for this
|
||||||
// page. The sane thing to do is return defaults.
|
// page. The sane thing to do is return defaults.
|
||||||
// TODO: the defaults are hard-coded in two places: here and the schema
|
// TODO: the defaults are hard-coded in two places: here and the schema
|
||||||
p.IsLocked = false
|
p.IsLocked = false
|
||||||
p.CommentCount = 0
|
p.CommentCount = 0
|
||||||
|
p.StickyCommentHex = "none"
|
||||||
} else {
|
} else {
|
||||||
logger.Errorf("error scanning page: %v", err)
|
logger.Errorf("error scanning page: %v", err)
|
||||||
return page{}, errorInternal
|
return page{}, errorInternal
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ func pageUpdate(p page) error {
|
|||||||
// commentCount
|
// commentCount
|
||||||
statement := `
|
statement := `
|
||||||
INSERT INTO
|
INSERT INTO
|
||||||
pages (domain, path, isLocked)
|
pages (domain, path, isLocked, stickyCommentHex)
|
||||||
VALUES ($1, $2, $3 )
|
VALUES ($1, $2, $3, $4 )
|
||||||
ON CONFLICT (domain, path) DO
|
ON CONFLICT (domain, path) DO
|
||||||
UPDATE SET isLocked = $3;
|
UPDATE SET isLocked = $3, stickyCommentHex = $4;
|
||||||
`
|
`
|
||||||
_, err := db.Exec(statement, p.Domain, p.Path, p.IsLocked)
|
_, err := db.Exec(statement, p.Domain, p.Path, p.IsLocked, p.StickyCommentHex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error setting page attributes: %v", err)
|
logger.Errorf("error setting page attributes: %v", err)
|
||||||
return errorInternal
|
return errorInternal
|
||||||
|
|||||||
@@ -1,41 +1,81 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"html/template"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func redirectLogin(w http.ResponseWriter, r *http.Request) {
|
func redirectLogin(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, os.Getenv("ORIGIN")+"/login", 301)
|
http.Redirect(w, r, os.Getenv("ORIGIN")+"/login", 301)
|
||||||
}
|
}
|
||||||
|
|
||||||
type staticAssetPlugs struct {
|
type staticPlugs struct {
|
||||||
Origin string
|
|
||||||
}
|
|
||||||
|
|
||||||
type staticHtmlPlugs struct {
|
|
||||||
Origin string
|
Origin string
|
||||||
CdnPrefix string
|
CdnPrefix string
|
||||||
Footer template.HTML
|
Footer string
|
||||||
|
}
|
||||||
|
|
||||||
|
var asset map[string][]byte = make(map[string][]byte)
|
||||||
|
var contentType map[string]string = make(map[string]string)
|
||||||
|
var footer string
|
||||||
|
var compress bool
|
||||||
|
|
||||||
|
func fileDetemplate(f string) ([]byte, error) {
|
||||||
|
contents, err := ioutil.ReadFile(f)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot read file %s: %v", f, err)
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
x := string(contents)
|
||||||
|
x = strings.Replace(x, "[[[.Origin]]]", os.Getenv("ORIGIN"), -1)
|
||||||
|
x = strings.Replace(x, "[[[.CdnPrefix]]]", os.Getenv("CDN_PREFIX"), -1)
|
||||||
|
x = strings.Replace(x, "[[[.Footer]]]", footer, -1)
|
||||||
|
|
||||||
|
return []byte(x), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func footerInit() error {
|
||||||
|
contents, err := fileDetemplate(os.Getenv("STATIC") + "/footer.html")
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot init footer: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
footer = string(contents)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileLoad(f string) ([]byte, error) {
|
||||||
|
b, err := fileDetemplate(f)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot load file %s: %v", f, err)
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !compress {
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return gzipStatic(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func staticRouterInit(router *mux.Router) error {
|
func staticRouterInit(router *mux.Router) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
subdir := pathStrip(os.Getenv("ORIGIN"))
|
subdir := pathStrip(os.Getenv("ORIGIN"))
|
||||||
|
|
||||||
asset := make(map[string][]byte)
|
if err = footerInit(); err != nil {
|
||||||
gzippedAsset := make(map[string][]byte)
|
logger.Errorf("error initialising static router: %v", err)
|
||||||
|
return err
|
||||||
for _, dir := range []string{"js", "css", "images"} {
|
}
|
||||||
sl := string(os.PathSeparator)
|
|
||||||
dir = sl + dir
|
|
||||||
|
|
||||||
|
for _, dir := range []string{"/js", "/css", "/images"} {
|
||||||
files, err := ioutil.ReadDir(os.Getenv("STATIC") + dir)
|
files, err := ioutil.ReadDir(os.Getenv("STATIC") + dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot read directory %s%s: %v", os.Getenv("STATIC"), dir, err)
|
logger.Errorf("cannot read directory %s%s: %v", os.Getenv("STATIC"), dir, err)
|
||||||
@@ -43,108 +83,47 @@ func staticRouterInit(router *mux.Router) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
p := dir + sl + file.Name()
|
f := dir + "/" + file.Name()
|
||||||
|
asset[subdir+f], err = fileLoad(os.Getenv("STATIC") + f)
|
||||||
contents, err := ioutil.ReadFile(os.Getenv("STATIC") + p)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot read file %s%s: %v", os.Getenv("STATIC"), p, err)
|
logger.Errorf("cannot detemplate %s%s: %v", os.Getenv("STATIC"), f, err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix := ""
|
|
||||||
if dir == "/js" {
|
|
||||||
prefix = "window.commentoOrigin='" + os.Getenv("ORIGIN") + "';\n"
|
|
||||||
prefix += "window.commentoCdn='" + os.Getenv("CDN_PREFIX") + "';\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
gzip := (os.Getenv("GZIP_STATIC") == "true")
|
|
||||||
|
|
||||||
asset[subdir+p] = []byte(prefix + string(contents))
|
|
||||||
if gzip {
|
|
||||||
gzippedAsset[subdir+p], err = gzipStatic(asset[subdir+p])
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("error gzipping %s: %v", p, err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// faster than checking inside the handler
|
|
||||||
if !gzip {
|
|
||||||
router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path)))
|
|
||||||
w.Write(asset[r.URL.Path])
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path)))
|
|
||||||
w.Header().Set("Content-Encoding", "gzip")
|
|
||||||
w.Write(gzippedAsset[r.URL.Path])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer, err := ioutil.ReadFile(os.Getenv("STATIC") + string(os.PathSeparator) + "footer.html")
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("cannot read file footer.html: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pages := []string{
|
pages := []string{
|
||||||
"login",
|
"/login",
|
||||||
"forgot",
|
"/forgot",
|
||||||
"reset-password",
|
"/reset-password",
|
||||||
"signup",
|
"/signup",
|
||||||
"confirm-email",
|
"/confirm-email",
|
||||||
"dashboard",
|
"/dashboard",
|
||||||
"logout",
|
"/logout",
|
||||||
}
|
|
||||||
|
|
||||||
html := make(map[string]string)
|
|
||||||
for _, page := range pages {
|
|
||||||
html[subdir+page] = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, page := range pages {
|
for _, page := range pages {
|
||||||
sl := string(os.PathSeparator)
|
f := page + ".html"
|
||||||
page = sl + page
|
asset[subdir+page], err = fileLoad(os.Getenv("STATIC") + f)
|
||||||
file := page + ".html"
|
|
||||||
|
|
||||||
contents, err := ioutil.ReadFile(os.Getenv("STATIC") + file)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot read file %s%s: %v", os.Getenv("STATIC"), file, err)
|
logger.Errorf("cannot detemplate %s%s: %v", os.Getenv("STATIC"), f, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := string(contents)
|
|
||||||
|
|
||||||
for {
|
|
||||||
t, err := template.New(page).Delims("[[[", "]]]").Parse(result)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("cannot parse %s%s template: %v", os.Getenv("STATIC"), file, err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
for p, _ := range asset {
|
||||||
t.Execute(&buf, &staticHtmlPlugs{
|
if path.Ext(p) != "" {
|
||||||
Origin: os.Getenv("ORIGIN"),
|
contentType[p] = mime.TypeByExtension(path.Ext(p))
|
||||||
CdnPrefix: os.Getenv("CDN_PREFIX"),
|
|
||||||
Footer: template.HTML(string(footer)),
|
|
||||||
})
|
|
||||||
|
|
||||||
result = buf.String()
|
|
||||||
if result == html[subdir+page] {
|
|
||||||
break
|
|
||||||
} else {
|
} else {
|
||||||
html[subdir+page] = result
|
contentType[p] = mime.TypeByExtension("html")
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, page := range pages {
|
router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
|
||||||
router.HandleFunc("/"+page, func(w http.ResponseWriter, r *http.Request) {
|
w.Header().Set("Content-Type", contentType[r.URL.Path])
|
||||||
fmt.Fprint(w, html[r.URL.Path])
|
if compress {
|
||||||
|
w.Header().Set("Content-Encoding", "gzip")
|
||||||
|
}
|
||||||
|
w.Write(asset[r.URL.Path])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,3 +43,16 @@ func bodyMarshal(w http.ResponseWriter, x map[string]interface{}) error {
|
|||||||
w.Write(resp)
|
w.Write(resp)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getIp(r *http.Request) string {
|
||||||
|
ip := r.RemoteAddr
|
||||||
|
if r.Header.Get("X-Forwarded-For") != "" {
|
||||||
|
ip = r.Header.Get("X-Forwarded-For")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUserAgent(r *http.Request) string {
|
||||||
|
return r.Header.Get("User-Agent")
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,13 +13,12 @@ func versionCheckStart() error {
|
|||||||
go func() {
|
go func() {
|
||||||
printedError := false
|
printedError := false
|
||||||
errorCount := 0
|
errorCount := 0
|
||||||
|
latestSeen := ""
|
||||||
|
|
||||||
for {
|
for {
|
||||||
time.Sleep(5 * time.Minute)
|
time.Sleep(5 * time.Minute)
|
||||||
|
|
||||||
data := url.Values{
|
data := url.Values{
|
||||||
"origin": {os.Getenv("ORIGIN")},
|
|
||||||
"edition": {edition},
|
|
||||||
"version": {version},
|
"version": {version},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +63,9 @@ func versionCheckStart() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.NewUpdate {
|
if r.NewUpdate && r.Latest != latestSeen {
|
||||||
logger.Infof("New update available! Latest version: %s", r.Latest)
|
logger.Infof("New update available! Latest version: %s", r.Latest)
|
||||||
|
latestSeen = r.Latest
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCount = 0
|
errorCount = 0
|
||||||
|
|||||||
7
db/20181007230906-store-version.sql
Normal file
7
db/20181007230906-store-version.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS config (
|
||||||
|
version TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO
|
||||||
|
config (version)
|
||||||
|
VALUES ('v1.1.3');
|
||||||
2
db/20181007231407-v1.1.4.sql
Normal file
2
db/20181007231407-v1.1.4.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
UPDATE config
|
||||||
|
SET version = 'v1.2.0';
|
||||||
2
db/20181218183803-sticky-comments.sql
Normal file
2
db/20181218183803-sticky-comments.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE pages
|
||||||
|
ADD stickyCommentHex TEXT NOT NULL DEFAULT 'none';
|
||||||
2
db/20181228114101-v1.4.0.sql
Normal file
2
db/20181228114101-v1.4.0.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
UPDATE config
|
||||||
|
SET version = 'v1.4.0';
|
||||||
@@ -2,7 +2,7 @@ version: '3'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
server:
|
||||||
image: registry.gitlab.com/commento/commento-ce
|
image: registry.gitlab.com/commento/commento
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
28
etc/bsd-rc/commento
Executable file
28
etc/bsd-rc/commento
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# PROVIDE: commento
|
||||||
|
# REQUIRE: LOGIN postgresql
|
||||||
|
# KEYWORD: shutdown
|
||||||
|
|
||||||
|
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
|
||||||
|
|
||||||
|
. /etc/rc.subr
|
||||||
|
|
||||||
|
desc="Commento daemon"
|
||||||
|
name=commento
|
||||||
|
rcvar=commento_enable
|
||||||
|
|
||||||
|
load_rc_config $name
|
||||||
|
|
||||||
|
: ${commento_enable:=NO}
|
||||||
|
|
||||||
|
commento_env="COMMENTO_ORIGIN=https://commento.example.com \
|
||||||
|
COMMENTO_PORT=8080 \
|
||||||
|
COMMENTO_POSTGRES=postgres://commento:commento@db:5432/commento?sslmode=disable \
|
||||||
|
COMMENTO_STATIC=/usr/local/share/commento"
|
||||||
|
commento_user=www
|
||||||
|
|
||||||
|
command="/usr/local/bin/commento"
|
||||||
|
command_args=" >> /var/log/commento/${name}.log 2>&1 &"
|
||||||
|
|
||||||
|
run_rc_command "$1"
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# PROVIDE: commento_ce
|
|
||||||
# REQUIRE: LOGIN postgresql
|
|
||||||
# KEYWORD: shutdown
|
|
||||||
|
|
||||||
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
|
|
||||||
|
|
||||||
. /etc/rc.subr
|
|
||||||
|
|
||||||
desc="Commento CE daemon"
|
|
||||||
name=commento_ce
|
|
||||||
rcvar=commento_ce_enable
|
|
||||||
|
|
||||||
load_rc_config $name
|
|
||||||
|
|
||||||
: ${commento_ce_enable:=NO}
|
|
||||||
|
|
||||||
commento_ce_env="COMMENTO_ORIGIN=https://commento.example.com \
|
|
||||||
COMMENTO_PORT=8080 \
|
|
||||||
COMMENTO_POSTGRES=postgres://commento:commento@db:5432/commento?sslmode=disable \
|
|
||||||
COMMENTO_STATIC=/usr/local/share/commento-ce"
|
|
||||||
commento_ce_user=www
|
|
||||||
|
|
||||||
command="/usr/local/bin/commento-ce"
|
|
||||||
command_args=" >> /var/log/commento_ce/${name}.log 2>&1 &"
|
|
||||||
|
|
||||||
run_rc_command "$1"
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Commento-CE daemon service
|
Description=Commento daemon service
|
||||||
After=network.target postgresql.service
|
After=network.target postgresql.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/commento-ce
|
ExecStart=/usr/bin/commento
|
||||||
Environment=COMMENTO_ORIGIN=https://commento.example.com
|
Environment=COMMENTO_ORIGIN=https://commento.example.com
|
||||||
Environment=COMMENTO_PORT=8080
|
Environment=COMMENTO_PORT=8080
|
||||||
Environment=COMMENTO_POSTGRES=postgres://commento:commento@db:5432/commento?sslmode=disable
|
Environment=COMMENTO_POSTGRES=postgres://commento:commento@db:5432/commento?sslmode=disable
|
||||||
Environment=COMMENTO_STATIC=/usr/share/commento-ce
|
Environment=COMMENTO_STATIC=/usr/share/commento
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
33
frontend/.eslintrc
Normal file
33
frontend/.eslintrc
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"$": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-bitwise": 2,
|
||||||
|
"camelcase": 2,
|
||||||
|
"brace-style": ["error", "1tbs"],
|
||||||
|
"curly": ["error", "all"],
|
||||||
|
"eqeqeq": ["error", "smart"],
|
||||||
|
"indent": ["error", 2],
|
||||||
|
"no-use-before-define": [
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"functions": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"new-cap": 2,
|
||||||
|
"no-caller": 2,
|
||||||
|
"quotes": [
|
||||||
|
2,
|
||||||
|
"double"
|
||||||
|
],
|
||||||
|
"no-unused-vars": 2,
|
||||||
|
"strict": [
|
||||||
|
2,
|
||||||
|
"function"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
1
frontend/.gitignore
vendored
1
frontend/.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
.sass-cache
|
.sass-cache
|
||||||
|
node_modules/
|
||||||
|
|||||||
@@ -1,117 +1,13 @@
|
|||||||
SHELL = bash
|
|
||||||
|
|
||||||
# list of JS files to be built
|
|
||||||
JS_BUILD = jquery.js vue.js highlight.js chartist.js login.js forgot.js reset.js signup.js dashboard.js logout.js commento.js
|
|
||||||
|
|
||||||
jquery.js = jquery.js
|
|
||||||
vue.js = vue.js
|
|
||||||
highlight.js = highlight.js
|
|
||||||
chartist.js = chartist.js
|
|
||||||
login.js = utils.js http.js auth-common.js login.js
|
|
||||||
forgot.js = utils.js http.js forgot.js
|
|
||||||
reset.js = utils.js http.js reset.js
|
|
||||||
signup.js = utils.js http.js auth-common.js signup.js
|
|
||||||
dashboard.js = utils.js http.js errors.js self.js dashboard.js dashboard-setting.js dashboard-domain.js dashboard-installation.js dashboard-general.js dashboard-moderation.js dashboard-statistics.js dashboard-import.js dashboard-danger.js
|
|
||||||
logout.js = utils.js logout.js
|
|
||||||
commento.js = commento.js
|
|
||||||
|
|
||||||
# for each file in $(JS_BUILD), list its composition
|
|
||||||
|
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
DEVEL_BUILD_DIR = $(BUILD_DIR)/devel
|
GULP = node_modules/.bin/gulp
|
||||||
PROD_BUILD_DIR = $(BUILD_DIR)/prod
|
|
||||||
|
|
||||||
HTML_SRC_DIR = .
|
devel:
|
||||||
HTML_SRC_FILES = $(wildcard $(HTML_SRC_DIR)/*.html)
|
yarn install
|
||||||
HTML_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)
|
$(GULP) devel
|
||||||
HTML_DEVEL_BUILD_FILES = $(patsubst $(HTML_SRC_DIR)/%, $(HTML_DEVEL_BUILD_DIR)/%, $(HTML_SRC_FILES))
|
|
||||||
HTML_PROD_BUILD_DIR = $(PROD_BUILD_DIR)
|
|
||||||
HTML_PROD_BUILD_FILES = $(patsubst $(HTML_SRC_DIR)/%, $(HTML_PROD_BUILD_DIR)/%, $(HTML_SRC_FILES))
|
|
||||||
|
|
||||||
HTML_MINIFIER = html-minifier
|
prod:
|
||||||
HTML_MINIFIER_FLAGS = --collapse-whitespace --remove-comments
|
yarn install
|
||||||
|
$(GULP) prod
|
||||||
JS_SRC_DIR = js
|
|
||||||
JS_SRC_FILES = $(wildcard $(JS_SRC_DIR)/*.js)
|
|
||||||
JS_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)/js
|
|
||||||
JS_DEVEL_BUILD_FILES = $(addprefix $(JS_DEVEL_BUILD_DIR)/, $(JS_BUILD))
|
|
||||||
JS_PROD_BUILD_DIR = $(PROD_BUILD_DIR)/js
|
|
||||||
JS_PROD_BUILD_FILES = $(addprefix $(JS_PROD_BUILD_DIR)/, $(JS_BUILD))
|
|
||||||
|
|
||||||
JS_MINIFIER = uglifyjs
|
|
||||||
JS_MINIFIER_FLAGS = --compress --mangle
|
|
||||||
|
|
||||||
SASS_SRC_DIR = sass
|
|
||||||
SASS_SRC_FILES = $(wildcard $(SASS_SRC_DIR)/*.scss)
|
|
||||||
CSS_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)/css
|
|
||||||
CSS_DEVEL_BUILD_FILES = $(patsubst $(SASS_SRC_DIR)/%.scss, $(CSS_DEVEL_BUILD_DIR)/%.css, $(SASS_SRC_FILES))
|
|
||||||
CSS_PROD_BUILD_DIR = $(PROD_BUILD_DIR)/css
|
|
||||||
CSS_PROD_BUILD_FILES = $(patsubst $(SASS_SRC_DIR)/%.scss, $(CSS_PROD_BUILD_DIR)/%.css, $(SASS_SRC_FILES))
|
|
||||||
|
|
||||||
CSS = sass
|
|
||||||
CSS_DEVEL_FLAGS =
|
|
||||||
CSS_PROD_FLAGS = $(CSS_DEVEL_FLAGS) --style compressed
|
|
||||||
|
|
||||||
IMGS_SRC_DIR = images
|
|
||||||
IMGS_SRC_FILES = $(wildcard $(IMGS_SRC_DIR)/*)
|
|
||||||
IMGS_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)/images
|
|
||||||
IMGS_DEVEL_BUILD_FILES = $(patsubst $(IMGS_SRC_DIR)/%, $(IMGS_DEVEL_BUILD_DIR)/%, $(IMGS_SRC_FILES))
|
|
||||||
IMGS_PROD_BUILD_DIR = $(PROD_BUILD_DIR)/images
|
|
||||||
IMGS_PROD_BUILD_FILES = $(patsubst $(IMGS_SRC_DIR)/%, $(IMGS_PROD_BUILD_DIR)/%, $(IMGS_SRC_FILES))
|
|
||||||
|
|
||||||
devel: devel-html devel-js devel-css devel-imgs
|
|
||||||
|
|
||||||
prod: devel prod-html prod-js prod-css prod-imgs
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -rf $(BUILD_DIR);
|
-rm -rf $(BUILD_DIR);
|
||||||
|
|
||||||
devel-html: $(HTML_DEVEL_BUILD_FILES)
|
|
||||||
|
|
||||||
$(HTML_DEVEL_BUILD_FILES): $(HTML_DEVEL_BUILD_DIR)/%.html: $(HTML_SRC_DIR)/%.html
|
|
||||||
cp $^ $@;
|
|
||||||
|
|
||||||
prod-html: $(HTML_PROD_BUILD_FILES)
|
|
||||||
|
|
||||||
$(HTML_PROD_BUILD_FILES): $(HTML_PROD_BUILD_DIR)/%.html: $(HTML_DEVEL_BUILD_DIR)/%.html
|
|
||||||
$(HTML_MINIFIER) $(HTML_MINIFIER_FLAGS) -o $@ $^;
|
|
||||||
|
|
||||||
devel-js: $(JS_DEVEL_BUILD_FILES)
|
|
||||||
|
|
||||||
.SECONDEXPANSION:
|
|
||||||
$(JS_DEVEL_BUILD_FILES): $(JS_DEVEL_BUILD_DIR)/%.js: $$(addprefix $$(JS_SRC_DIR)/, $$(%.js))
|
|
||||||
>$@; \
|
|
||||||
for f in $^; do \
|
|
||||||
printf "// %s\n" "$$f" >>$@; \
|
|
||||||
cat $$f >>$@; \
|
|
||||||
printf "\n" >>$@; \
|
|
||||||
done;
|
|
||||||
|
|
||||||
prod-js: $(JS_PROD_BUILD_FILES)
|
|
||||||
|
|
||||||
$(JS_PROD_BUILD_FILES): $(JS_PROD_BUILD_DIR)/%.js: $(JS_DEVEL_BUILD_DIR)/%.js
|
|
||||||
$(JS_MINIFIER) $(JS_MINIFIER_FLAGS) -o $@ $^;
|
|
||||||
|
|
||||||
devel-css: $(CSS_DEVEL_BUILD_FILES)
|
|
||||||
|
|
||||||
$(CSS_DEVEL_BUILD_FILES): $(CSS_DEVEL_BUILD_DIR)/%.css: $(SASS_SRC_DIR)/%.scss $(SASS_SRC_FILES)
|
|
||||||
$(CSS) $(CSS_DEVEL_FLAGS) $< $@;
|
|
||||||
|
|
||||||
prod-css: $(CSS_PROD_BUILD_FILES)
|
|
||||||
|
|
||||||
$(CSS_PROD_BUILD_FILES): $(CSS_PROD_BUILD_DIR)/%.css: $(SASS_SRC_DIR)/%.scss
|
|
||||||
$(CSS) $(CSS_PROD_FLAGS) $^ $@;
|
|
||||||
|
|
||||||
$(shell mkdir -p $(HTML_DEVEL_BUILD_DIR) $(JS_DEVEL_BUILD_DIR) $(CSS_DEVEL_BUILD_DIR) $(HTML_PROD_BUILD_DIR) $(JS_PROD_BUILD_DIR) $(CSS_PROD_BUILD_DIR))
|
|
||||||
|
|
||||||
devel-imgs: $(IMGS_DEVEL_BUILD_FILES)
|
|
||||||
|
|
||||||
$(IMGS_DEVEL_BUILD_FILES): $(IMGS_DEVEL_BUILD_DIR)/%: $(IMGS_SRC_DIR)/%
|
|
||||||
cp $^ $@;
|
|
||||||
|
|
||||||
prod-imgs: $(IMGS_PROD_BUILD_FILES)
|
|
||||||
|
|
||||||
$(IMGS_PROD_BUILD_FILES): $(IMGS_PROD_BUILD_DIR)/%: $(IMGS_SRC_DIR)/%
|
|
||||||
cp $^ $@
|
|
||||||
|
|
||||||
$(shell mkdir -p $(HTML_DEVEL_BUILD_DIR) $(JS_DEVEL_BUILD_DIR) $(CSS_DEVEL_BUILD_DIR) $(IMGS_DEVEL_BUILD_DIR) $(HTML_PROD_BUILD_DIR) $(JS_PROD_BUILD_DIR) $(CSS_PROD_BUILD_DIR) $(IMGS_PROD_BUILD_DIR))
|
|
||||||
|
|||||||
@@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window.selfGet(function() {
|
window.commento.selfGet(function() {
|
||||||
window.vueConstruct(function() {
|
window.commento.vueConstruct(function() {
|
||||||
window.navbarFill();
|
window.commento.navbarFill();
|
||||||
window.domainRefresh();
|
window.commento.domainRefresh();
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$("ul.tabs li").click(function(){
|
$("ul.tabs li").click(function(){
|
||||||
var tab_id = $(this).attr("data-tab");
|
var tab_id = $(this).attr("data-tab");
|
||||||
@@ -51,13 +51,13 @@
|
|||||||
It's so quiet in here.
|
It's so quiet in here.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pane-setting" v-for="domain in domains" v-on:click="window.domainSelect(domain.domain)" id="{{domain.hex}}" v-bind:class="{selected: domain.selected}" v-if="domain.show">
|
<div class="pane-setting" v-for="domain in domains" v-on:click="window.commento.domainSelect(domain.domain)" id="{{domain.hex}}" v-bind:class="{selected: domain.selected}" v-if="domain.show">
|
||||||
<div class="pane-setting-inside">
|
<div class="pane-setting-inside">
|
||||||
<div class="setting-title">{{domain.name}}</div>
|
<div class="setting-title">{{domain.name}}</div>
|
||||||
<div class="setting-subtitle">{{domain.domain}}</div>
|
<div class="setting-subtitle">{{domain.domain}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pane-setting" id="domain-add" onclick="window.location.hash='#new-domain-modal'">
|
<div class="pane-setting" id="domain-add" onclick="document.location.hash='#new-domain-modal'">
|
||||||
<div class="pane-setting-inside super-setting">
|
<div class="pane-setting-inside super-setting">
|
||||||
<div class="super-setting-title">+</div>
|
<div class="super-setting-title">+</div>
|
||||||
<div class="super-setting-text">New Domain</div>
|
<div class="super-setting-text">New Domain</div>
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pane-middle">
|
<div class="pane-middle">
|
||||||
<div v-if="showSettings" class="pane-setting" v-for="setting in settings" v-on:click="window.settingSelect(setting.id)" id="{{setting.id}}" v-bind:class="{selected: setting.selected}">
|
<div v-if="showSettings" class="pane-setting" v-for="setting in settings" v-on:click="window.commento.settingSelect(setting.id)" id="{{setting.id}}" v-bind:class="{selected: setting.selected}">
|
||||||
<div class="pane-setting-inside">
|
<div class="pane-setting-inside">
|
||||||
<div class="setting-title">{{setting.text}}</div>
|
<div class="setting-title">{{setting.text}}</div>
|
||||||
<div class="setting-subtitle">{{setting.meaning}}</div>
|
<div class="setting-subtitle">{{setting.meaning}}</div>
|
||||||
@@ -156,14 +156,14 @@
|
|||||||
<div class="commento-email-container">
|
<div class="commento-email-container">
|
||||||
<div class="commento-email">
|
<div class="commento-email">
|
||||||
<input class="commento-input" type="text" id="new-mod" placeholder="Email">
|
<input class="commento-input" type="text" id="new-mod" placeholder="Email">
|
||||||
<button id="new-mod-button" class="commento-email-button" onclick="window.moderatorNewHandler()">Add moderator</button>
|
<button id="new-mod-button" class="commento-email-button" onclick="window.commento.moderatorNewHandler()">Add moderator</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mod-emails-container">
|
<div class="mod-emails-container">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="mod-email" v-for="email in domains[cd].moderators" v-if="domains[cd].moderators.length > 0">
|
<div class="mod-email" v-for="email in domains[cd].moderators" v-if="domains[cd].moderators.length > 0">
|
||||||
<div class="email">{{email.email}}</div>
|
<div class="email">{{email.email}}</div>
|
||||||
<div class="delete" v-on:click="window.moderatorDeleteHandler(email.email)">Delete</div>
|
<div class="delete" v-on:click="window.commento.moderatorDeleteHandler(email.email)">Delete</div>
|
||||||
<div class="date">added {{email.timeAgo}}</div>
|
<div class="date">added {{email.timeAgo}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
<div id="new-domain-error" class="modal-error-box"></div>
|
<div id="new-domain-error" class="modal-error-box"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<button id="save-general-button" onclick="window.generalSaveHandler()" class="button">Save Changes</button>
|
<button id="save-general-button" onclick="window.commento.generalSaveHandler()" class="button">Save Changes</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
<div class="commento-email-container">
|
<div class="commento-email-container">
|
||||||
<div class="commento-email">
|
<div class="commento-email">
|
||||||
<input class="commento-input" type="text" id="disqus-url" placeholder="https://media.disqus.com/uploads/...">
|
<input class="commento-input" type="text" id="disqus-url" placeholder="https://media.disqus.com/uploads/...">
|
||||||
<button id="disqus-import-button" class="commento-email-button" onclick="importDisqus()">Import</button>
|
<button id="disqus-import-button" class="commento-email-button" onclick="window.commento.importDisqus()">Import</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="subtext-container">
|
<div class="subtext-container">
|
||||||
@@ -286,7 +286,7 @@
|
|||||||
If you desire to re-allow comments again on your website, you can do so. You can, of course, freeze the site again in the future.
|
If you desire to re-allow comments again on your website, you can do so. You can, of course, freeze the site again in the future.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="window.location.hash='#unfreeze-domain-modal'" class="button green-button">Unfreeze Domain</button>
|
<button onclick="document.location.hash='#unfreeze-domain-modal'" class="button green-button">Unfreeze Domain</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="box" v-if="domains[cd].state != 'frozen'">
|
<div class="box" v-if="domains[cd].state != 'frozen'">
|
||||||
@@ -294,7 +294,7 @@
|
|||||||
If you desire to temporarily freeze new comments (domain-wide), thereby making it read-only, you can do so. You can choose to unfreeze later; this is temporary.
|
If you desire to temporarily freeze new comments (domain-wide), thereby making it read-only, you can do so. You can choose to unfreeze later; this is temporary.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="orange-button" onclick="window.location.hash='#freeze-domain-modal'" class="button orange-button">Freeze Domain</button>
|
<button id="orange-button" onclick="document.location.hash='#freeze-domain-modal'" class="button orange-button">Freeze Domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -305,7 +305,7 @@
|
|||||||
Want to completely remove Commento from your website? This will permanently delete all comments and there is literally no way to retrieve your data once you do this.
|
Want to completely remove Commento from your website? This will permanently delete all comments and there is literally no way to retrieve your data once you do this.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="big-red-button" class="button big-red-button" onclick="window.location.hash='#delete-domain-modal'">Delete Domain</button>
|
<button id="big-red-button" class="button big-red-button" onclick="document.location.hash='#delete-domain-modal'">Delete Domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -323,7 +323,7 @@
|
|||||||
Are you absolutely sure you want to freeze your domain, thereby making it read-only? You can choose to unfreeze later; this is temporary.
|
Are you absolutely sure you want to freeze your domain, thereby making it read-only? You can choose to unfreeze later; this is temporary.
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-contents">
|
<div class="modal-contents">
|
||||||
<button id="orange-button" class="button orange-button" onclick="window.domainFreezeHandler()">Freeze Domain</button>
|
<button id="orange-button" class="button orange-button" onclick="window.commento.domainFreezeHandler()">Freeze Domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -336,7 +336,7 @@
|
|||||||
Are you absolutely sure you want to unfreeze your domain? This will re-allow new comments. You can choose to freeze again in the future.
|
Are you absolutely sure you want to unfreeze your domain? This will re-allow new comments. You can choose to freeze again in the future.
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-contents">
|
<div class="modal-contents">
|
||||||
<button id="blue-button" class="button green-button" onclick="window.domainUnfreezeHandler()">Unfreeze Domain</button>
|
<button id="blue-button" class="button green-button" onclick="window.commento.domainUnfreezeHandler()">Unfreeze Domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
Are you absolutely sure? This will permanently delete all comments and there is literally no way to retrieve your data once you do this.
|
Are you absolutely sure? This will permanently delete all comments and there is literally no way to retrieve your data once you do this.
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-contents">
|
<div class="modal-contents">
|
||||||
<button id="big-red-button" class="button big-red-button" onclick="window.domainDeleteHandler()">Delete Domain</button>
|
<button id="big-red-button" class="button big-red-button" onclick="window.commento.domainDeleteHandler()">Delete Domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -374,7 +374,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="new-domain-error" class="modal-error-box"></div>
|
<div id="new-domain-error" class="modal-error-box"></div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<button id="add-site-button" onclick="window.domainNewHandler()" class="button">Add Domain</button>
|
<button id="add-site-button" onclick="window.commento.domainNewHandler()" class="button">Add Domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="err" id="err"></div>
|
<div class="err" id="err"></div>
|
||||||
<div class="msg" id="msg"></div>
|
<div class="msg" id="msg"></div>
|
||||||
<button id="reset-button" class="button" onclick="sendResetHex()">Send Reset Password Link</button>
|
<button id="reset-button" class="button" onclick="window.commento.sendResetHex()">Send Reset Password Link</button>
|
||||||
<a class="link" href="[[[.Origin]]]/login">Suddenly remembered your password? Login.</a>
|
<a class="link" href="[[[.Origin]]]/login">Suddenly remembered your password? Login.</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
139
frontend/gulpfile.js
Normal file
139
frontend/gulpfile.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const gulp = require("gulp");
|
||||||
|
const sass = require("gulp-sass");
|
||||||
|
const sourcemaps = require("gulp-sourcemaps");
|
||||||
|
const cleanCss = require("gulp-clean-css");
|
||||||
|
const htmlMinifier = require("gulp-html-minifier");
|
||||||
|
const uglify = require("gulp-uglify");
|
||||||
|
const concat = require("gulp-concat");
|
||||||
|
const rename = require("gulp-rename");
|
||||||
|
const eslint = require("gulp-eslint");
|
||||||
|
|
||||||
|
const develPath = "build/devel/";
|
||||||
|
const prodPath = "build/prod/";
|
||||||
|
const scssSrc = "./sass/*.scss";
|
||||||
|
const cssDir = "css/";
|
||||||
|
const imagesDir = "images/";
|
||||||
|
const imagesGlob = imagesDir + "**/*";
|
||||||
|
const jsDir = "js/";
|
||||||
|
const jsGlob = jsDir + "*.js";
|
||||||
|
const htmlGlob = "./*.html";
|
||||||
|
|
||||||
|
const jsCompileMap = {
|
||||||
|
"js/jquery.js": ["node_modules/jquery/dist/jquery.min.js"],
|
||||||
|
"js/vue.js": ["node_modules/vue/dist/vue.min.js"],
|
||||||
|
"js/highlight.js": ["node_modules/highlightjs/highlight.pack.min.js"],
|
||||||
|
"js/chartist.js": ["node_modules/chartist/dist/chartist.min.js"],
|
||||||
|
"js/login.js": [
|
||||||
|
"js/constants.js",
|
||||||
|
"js/utils.js",
|
||||||
|
"js/http.js",
|
||||||
|
"js/auth-common.js",
|
||||||
|
"js/login.js"
|
||||||
|
],
|
||||||
|
"js/forgot.js": [
|
||||||
|
"js/constants.js",
|
||||||
|
"js/utils.js",
|
||||||
|
"js/http.js",
|
||||||
|
"js/forgot.js"
|
||||||
|
],
|
||||||
|
"js/reset.js": [
|
||||||
|
"js/constants.js",
|
||||||
|
"js/utils.js",
|
||||||
|
"js/http.js",
|
||||||
|
"js/reset.js"
|
||||||
|
],
|
||||||
|
"js/signup.js": [
|
||||||
|
"js/constants.js",
|
||||||
|
"js/utils.js",
|
||||||
|
"js/http.js",
|
||||||
|
"js/auth-common.js",
|
||||||
|
"js/signup.js"
|
||||||
|
],
|
||||||
|
"js/dashboard.js": [
|
||||||
|
"js/constants.js",
|
||||||
|
"js/utils.js",
|
||||||
|
"js/http.js",
|
||||||
|
"js/errors.js",
|
||||||
|
"js/self.js",
|
||||||
|
"js/dashboard.js",
|
||||||
|
"js/dashboard-setting.js",
|
||||||
|
"js/dashboard-domain.js",
|
||||||
|
"js/dashboard-installation.js",
|
||||||
|
"js/dashboard-general.js",
|
||||||
|
"js/dashboard-moderation.js",
|
||||||
|
"js/dashboard-statistics.js",
|
||||||
|
"js/dashboard-import.js",
|
||||||
|
"js/dashboard-danger.js",
|
||||||
|
],
|
||||||
|
"js/logout.js": [
|
||||||
|
"js/constants.js",
|
||||||
|
"js/utils.js",
|
||||||
|
"js/logout.js"
|
||||||
|
],
|
||||||
|
"js/commento.js": ["js/commento.js"],
|
||||||
|
};
|
||||||
|
|
||||||
|
gulp.task("scss-devel", function () {
|
||||||
|
return gulp.src(scssSrc)
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(sass({outputStyle: "expanded"}).on("error", sass.logError))
|
||||||
|
.pipe(sourcemaps.write())
|
||||||
|
.pipe(gulp.dest(develPath + cssDir));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("scss-prod", function () {
|
||||||
|
return gulp.src(scssSrc)
|
||||||
|
.pipe(sass({outputStyle: "compressed"}).on("error", sass.logError))
|
||||||
|
.pipe(cleanCss({compatibility: "ie8", level: 2}))
|
||||||
|
.pipe(gulp.dest(prodPath + cssDir));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("html-devel", function () {
|
||||||
|
gulp.src([htmlGlob]).pipe(gulp.dest(develPath));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("html-prod", function () {
|
||||||
|
gulp.src(htmlGlob)
|
||||||
|
.pipe(htmlMinifier({collapseWhitespace: true, removeComments: true}))
|
||||||
|
.pipe(gulp.dest(prodPath))
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("images-devel", function () {
|
||||||
|
gulp.src([imagesGlob]).pipe(gulp.dest(develPath + imagesDir));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("images-prod", function () {
|
||||||
|
gulp.src([imagesGlob]).pipe(gulp.dest(prodPath + imagesDir));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("js-devel", function () {
|
||||||
|
for (let outputFile in jsCompileMap) {
|
||||||
|
gulp.src(jsCompileMap[outputFile])
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(concat(outputFile))
|
||||||
|
.pipe(rename(outputFile))
|
||||||
|
.pipe(sourcemaps.write())
|
||||||
|
.pipe(gulp.dest(develPath))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("js-prod", function () {
|
||||||
|
for (let outputFile in jsCompileMap) {
|
||||||
|
gulp.src(jsCompileMap[outputFile])
|
||||||
|
.pipe(concat(outputFile))
|
||||||
|
.pipe(rename(outputFile))
|
||||||
|
.pipe(uglify())
|
||||||
|
.pipe(gulp.dest(prodPath))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("lint", function () {
|
||||||
|
return gulp.src(jsGlob)
|
||||||
|
.pipe(eslint())
|
||||||
|
.pipe(eslint.failAfterError())
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("devel", ["scss-devel", "html-devel", "images-devel", "lint", "js-devel"]);
|
||||||
|
gulp.task("prod", ["scss-prod", "html-prod", "images-prod", "lint", "js-prod"]);
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// Redirect the user to the dashboard if there's a cookie. If the cookie is
|
// Redirect the user to the dashboard if there's a cookie. If the cookie is
|
||||||
// invalid, they would be redirected back to the login page *after* the
|
// invalid, they would be redirected back to the login page *after* the
|
||||||
// cookie is deleted.
|
// cookie is deleted.
|
||||||
global.loggedInRedirect = function() {
|
global.loggedInRedirect = function() {
|
||||||
if (global.cookieGet("commentoOwnerToken") !== undefined)
|
if (global.cookieGet("commentoOwnerToken") !== undefined) {
|
||||||
document.location = global.commentoOrigin + "/dashboard";
|
document.location = global.origin + "/dashboard";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Prefills the email field from the URL parameter.
|
// Prefills the email field from the URL parameter.
|
||||||
global.prefillEmail = function() {
|
global.prefillEmail = function() {
|
||||||
if (paramGet("email") != undefined) {
|
if (paramGet("email") !== undefined) {
|
||||||
$("#email").val(paramGet("email"));
|
$("#email").val(paramGet("email"));
|
||||||
$("#password").click();
|
$("#password").click();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
13
frontend/js/constants.js
Normal file
13
frontend/js/constants.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
|
if (window.commento === undefined) {
|
||||||
|
window.commento = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.commento.origin = "[[[.Origin]]]";
|
||||||
|
window.commento.cdn = "[[[.CdnPrefix]]]";
|
||||||
|
|
||||||
|
} (window, document));
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// Opens the danger zone.
|
// Opens the danger zone.
|
||||||
global.dangerOpen = function() {
|
global.dangerOpen = function() {
|
||||||
@@ -11,9 +12,10 @@
|
|||||||
global.domainDeleteHandler = function() {
|
global.domainDeleteHandler = function() {
|
||||||
var data = global.dashboard.$data;
|
var data = global.dashboard.$data;
|
||||||
|
|
||||||
domainDelete(data.domains[data.cd].domain, function(success) {
|
global.domainDelete(data.domains[data.cd].domain, function(success) {
|
||||||
if (success)
|
if (success) {
|
||||||
document.location = global.commentoOrigin + '/dashboard';
|
document.location = global.origin + "/dashboard";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +25,7 @@
|
|||||||
var data = global.dashboard.$data;
|
var data = global.dashboard.$data;
|
||||||
|
|
||||||
data.domains[data.cd].state = "frozen"
|
data.domains[data.cd].state = "frozen"
|
||||||
domainUpdate(data.domains[data.cd])
|
global.domainUpdate(data.domains[data.cd])
|
||||||
document.location.hash = "#modal-close";
|
document.location.hash = "#modal-close";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,9 +35,9 @@
|
|||||||
var data = global.dashboard.$data;
|
var data = global.dashboard.$data;
|
||||||
|
|
||||||
data.domains[data.cd].state = "unfrozen"
|
data.domains[data.cd].state = "unfrozen"
|
||||||
domainUpdate(data.domains[data.cd])
|
global.domainUpdate(data.domains[data.cd])
|
||||||
document.location.hash = "#modal-close";
|
document.location.hash = "#modal-close";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// Selects a domain.
|
// Selects a domain.
|
||||||
global.domainSelect = function(domain) {
|
global.domainSelect = function(domain) {
|
||||||
@@ -6,19 +7,19 @@
|
|||||||
var domains = data.domains;
|
var domains = data.domains;
|
||||||
|
|
||||||
for (var i = 0; i < domains.length; i++) {
|
for (var i = 0; i < domains.length; i++) {
|
||||||
if (domains[i].domain == domain) {
|
if (domains[i].domain === domain) {
|
||||||
vs("frozen", domains[i].state == "frozen");
|
global.vs("frozen", domains[i].state === "frozen");
|
||||||
domains[i].selected = true;
|
domains[i].selected = true;
|
||||||
data.cd = i;
|
data.cd = i;
|
||||||
data.importedComments = domains[i].importedComments;
|
data.importedComments = domains[i].importedComments;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
domains[i].selected = false;
|
domains[i].selected = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data.showSettings = true;
|
data.showSettings = true;
|
||||||
|
|
||||||
settingDeselectAll();
|
global.settingDeselectAll();
|
||||||
$(".view").hide();
|
$(".view").hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,9 +29,10 @@
|
|||||||
var data = global.dashboard.$data;
|
var data = global.dashboard.$data;
|
||||||
var domains = data.domains;
|
var domains = data.domains;
|
||||||
|
|
||||||
for (var i = 0; i < domains.length; i++)
|
for (var i = 0; i < domains.length; i++) {
|
||||||
domains[i].selected = false;
|
domains[i].selected = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Creates a new domain.
|
// Creates a new domain.
|
||||||
@@ -42,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
global.buttonDisable("#add-site-button");
|
global.buttonDisable("#add-site-button");
|
||||||
global.post(global.commentoOrigin + "/api/domain/new", json, function(resp) {
|
global.post(global.origin + "/api/domain/new", json, function(resp) {
|
||||||
global.buttonEnable("#add-site-button");
|
global.buttonEnable("#add-site-button");
|
||||||
|
|
||||||
$("#new-domain-name").val("");
|
$("#new-domain-name").val("");
|
||||||
@@ -69,7 +71,7 @@
|
|||||||
"ownerToken": global.cookieGet("commentoOwnerToken"),
|
"ownerToken": global.cookieGet("commentoOwnerToken"),
|
||||||
};
|
};
|
||||||
|
|
||||||
global.post(global.commentoOrigin + "/api/domain/list", json, function(resp) {
|
global.post(global.origin + "/api/domain/list", json, function(resp) {
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
global.globalErrorShow(resp.message);
|
global.globalErrorShow(resp.message);
|
||||||
return;
|
return;
|
||||||
@@ -98,8 +100,9 @@
|
|||||||
|
|
||||||
global.vs("domains", resp.domains);
|
global.vs("domains", resp.domains);
|
||||||
|
|
||||||
if (callback !== undefined)
|
if (callback !== undefined) {
|
||||||
callback();
|
callback();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,9 +114,10 @@
|
|||||||
"domain": domain,
|
"domain": domain,
|
||||||
};
|
};
|
||||||
|
|
||||||
global.post(global.commentoOrigin + "/api/domain/update", json, function(resp) {
|
global.post(global.origin + "/api/domain/update", json, function(resp) {
|
||||||
if (callback !== undefined)
|
if (callback !== undefined) {
|
||||||
callback(resp.success);
|
callback(resp.success);
|
||||||
|
}
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
global.globalErrorShow(resp.message);
|
global.globalErrorShow(resp.message);
|
||||||
@@ -130,15 +134,16 @@
|
|||||||
"domain": domain,
|
"domain": domain,
|
||||||
};
|
};
|
||||||
|
|
||||||
global.post(global.commentoOrigin + "/api/domain/delete", json, function(resp) {
|
global.post(global.origin + "/api/domain/delete", json, function(resp) {
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
global.globalErrorShow(resp.message);
|
global.globalErrorShow(resp.message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback !== undefined)
|
if (callback !== undefined) {
|
||||||
callback(resp.success);
|
callback(resp.success);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Opens the general settings window.
|
// Opens the general settings window.
|
||||||
global.generalOpen = function() {
|
global.generalOpen = function() {
|
||||||
@@ -16,4 +19,4 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Opens the import window.
|
// Opens the import window.
|
||||||
global.importOpen = function() {
|
global.importOpen = function() {
|
||||||
@@ -6,7 +9,6 @@
|
|||||||
$("#import-view").show();
|
$("#import-view").show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
global.importDisqus = function() {
|
global.importDisqus = function() {
|
||||||
var url = $("#disqus-url").val();
|
var url = $("#disqus-url").val();
|
||||||
var data = global.dashboard.$data;
|
var data = global.dashboard.$data;
|
||||||
@@ -18,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
global.buttonDisable("#disqus-import-button");
|
global.buttonDisable("#disqus-import-button");
|
||||||
global.post(global.commentoOrigin + "/api/domain/import/disqus", json, function(resp) {
|
global.post(global.origin + "/api/domain/import/disqus", json, function(resp) {
|
||||||
global.buttonEnable("#disqus-import-button");
|
global.buttonEnable("#disqus-import-button");
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
@@ -28,8 +30,8 @@
|
|||||||
|
|
||||||
$("#disqus-import-button").hide();
|
$("#disqus-import-button").hide();
|
||||||
|
|
||||||
globalOKShow("Imported " + resp.numImported + " comments!");
|
global.globalOKShow("Imported " + resp.numImported + " comments!");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Opens the installation view.
|
// Opens the installation view.
|
||||||
global.installationOpen = function() {
|
global.installationOpen = function() {
|
||||||
var data = global.dashboard.$data;
|
var html = "" +
|
||||||
|
"<div id=\"commento\"></div>\n" +
|
||||||
var html = '' +
|
"<script src=\"" + global.cdn + "/js/commento.js\"><\/script>\n" +
|
||||||
'<div id="commento"></div>\n' +
|
"";
|
||||||
'<script src="' + window.commentoCdn + '/js/commento.js"><\/script>\n' +
|
|
||||||
'';
|
|
||||||
|
|
||||||
$("#code-div").text(html);
|
$("#code-div").text(html);
|
||||||
|
|
||||||
$('pre code').each(function(i, block) {
|
$("pre code").each(function(i, block) {
|
||||||
hljs.highlightBlock(block);
|
hljs.highlightBlock(block);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -19,4 +20,4 @@
|
|||||||
$("#installation-view").show();
|
$("#installation-view").show();
|
||||||
};
|
};
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Opens the moderatiosn settings window.
|
// Opens the moderatiosn settings window.
|
||||||
global.moderationOpen = function() {
|
global.moderationOpen = function() {
|
||||||
@@ -20,16 +23,16 @@
|
|||||||
|
|
||||||
var idx = -1;
|
var idx = -1;
|
||||||
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
|
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
|
||||||
if (data.domains[data.cd].moderators[i].email == email) {
|
if (data.domains[data.cd].moderators[i].email === email) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx == -1) {
|
if (idx === -1) {
|
||||||
data.domains[data.cd].moderators.push({"email": email, "timeAgo": "just now"});
|
data.domains[data.cd].moderators.push({"email": email, "timeAgo": "just now"});
|
||||||
global.buttonDisable("#new-mod-button");
|
global.buttonDisable("#new-mod-button");
|
||||||
global.post(global.commentoOrigin + "/api/domain/moderator/new", json, function(resp) {
|
global.post(global.origin + "/api/domain/moderator/new", json, function(resp) {
|
||||||
global.buttonEnable("#new-mod-button");
|
global.buttonEnable("#new-mod-button");
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
@@ -41,8 +44,7 @@
|
|||||||
$("#new-mod").val("");
|
$("#new-mod").val("");
|
||||||
$("#new-mod").focus();
|
$("#new-mod").focus();
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
global.globalErrorShow("Already a moderator.");
|
global.globalErrorShow("Already a moderator.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,23 +62,23 @@
|
|||||||
|
|
||||||
var idx = -1;
|
var idx = -1;
|
||||||
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
|
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
|
||||||
if (data.domains[data.cd].moderators[i].email == email) {
|
if (data.domains[data.cd].moderators[i].email === email) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx != -1) {
|
if (idx !== -1) {
|
||||||
data.domains[data.cd].moderators.splice(idx, 1);
|
data.domains[data.cd].moderators.splice(idx, 1);
|
||||||
global.post(global.commentoOrigin + "/api/domain/moderator/delete", json, function(resp) {
|
global.post(global.origin + "/api/domain/moderator/delete", json, function(resp) {
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
global.globalErrorShow(resp.message);
|
global.globalErrorShow(resp.message);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
globalOKShow("Removed!");
|
global.globalOKShow("Removed!");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Sets the vue.js toggle to select and deselect panes visually.
|
// Sets the vue.js toggle to select and deselect panes visually.
|
||||||
function settingSelectCSS(id) {
|
function settingSelectCSS(id) {
|
||||||
@@ -6,12 +9,7 @@
|
|||||||
var settings = data.settings;
|
var settings = data.settings;
|
||||||
|
|
||||||
for (var i = 0; i < settings.length; i++) {
|
for (var i = 0; i < settings.length; i++) {
|
||||||
if (settings[i].id == id) {
|
settings[i].selected = settings[i].id === id;
|
||||||
settings[i].selected = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
settings[i].selected = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,9 +26,10 @@
|
|||||||
$(".original").addClass("current");
|
$(".original").addClass("current");
|
||||||
|
|
||||||
for (var i = 0; i < settings.length; i++) {
|
for (var i = 0; i < settings.length; i++) {
|
||||||
if (id == settings[i].id)
|
if (id === settings[i].id) {
|
||||||
settings[i].open();
|
settings[i].open();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -39,8 +38,9 @@
|
|||||||
var data = global.dashboard.$data;
|
var data = global.dashboard.$data;
|
||||||
var settings = data.settings;
|
var settings = data.settings;
|
||||||
|
|
||||||
for (var i = 0; i < settings.length; i++)
|
for (var i = 0; i < settings.length; i++) {
|
||||||
settings[i].selected = false;
|
settings[i].selected = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,35 +1,41 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
global.numberify = function(x) {
|
global.numberify = function(x) {
|
||||||
if (x == 0)
|
if (x === 0) {
|
||||||
return {"zeros": "000", "num": "", "units": ""}
|
return {"zeros": "000", "num": "", "units": ""}
|
||||||
|
}
|
||||||
|
|
||||||
if (x < 10)
|
if (x < 10) {
|
||||||
return {"zeros": "00", "num": x, "units": ""}
|
return {"zeros": "00", "num": x, "units": ""}
|
||||||
|
}
|
||||||
|
|
||||||
if (x < 100)
|
if (x < 100) {
|
||||||
return {"zeros": "0", "num": x, "units": ""}
|
return {"zeros": "0", "num": x, "units": ""}
|
||||||
|
}
|
||||||
|
|
||||||
if (x < 1000)
|
if (x < 1000) {
|
||||||
return {"zeros": "", "num": x, "units": ""}
|
return {"zeros": "", "num": x, "units": ""}
|
||||||
|
}
|
||||||
|
|
||||||
var res;
|
var res;
|
||||||
|
|
||||||
if (x < 1000000) {
|
if (x < 1000000) {
|
||||||
res = numberify((x/1000).toFixed(0))
|
res = global.numberify((x/1000).toFixed(0))
|
||||||
res.units = "K"
|
res.units = "K"
|
||||||
}
|
} else if (x < 1000000000) {
|
||||||
else if (x < 1000000000) {
|
res = global.numberify((x/1000000).toFixed(0))
|
||||||
res = numberify((x/1000000).toFixed(0))
|
|
||||||
res.units = "M"
|
res.units = "M"
|
||||||
}
|
} else if (x < 1000000000000) {
|
||||||
else if (x < 1000000000000) {
|
res = global.numberify((x/1000000000).toFixed(0))
|
||||||
res = numberify((x/1000000000).toFixed(0))
|
|
||||||
res.units = "B"
|
res.units = "B"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.num*10 % 10 == 0)
|
if (res.num*10 % 10 === 0) {
|
||||||
res.num = Math.ceil(res.num);
|
res.num = Math.ceil(res.num);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -43,11 +49,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(".view").hide();
|
$(".view").hide();
|
||||||
post(global.commentoOrigin + "/api/domain/statistics", json, function(resp) {
|
global.post(global.origin + "/api/domain/statistics", json, function(resp) {
|
||||||
$("#statistics-view").show();
|
$("#statistics-view").show();
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
globalErrorShow(resp.message);
|
global.globalErrorShow(resp.message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,13 +80,13 @@
|
|||||||
|
|
||||||
var labels = new Array();
|
var labels = new Array();
|
||||||
for (var i = 0; i < views.length; i++) {
|
for (var i = 0; i < views.length; i++) {
|
||||||
if ((views.length-i) % 7 == 0) {
|
if ((views.length-i) % 7 === 0) {
|
||||||
var x = (views.length-i)/7;
|
var x = (views.length-i)/7;
|
||||||
labels.push(x + " week" + (x > 1 ? "s" : "") + " ago");
|
labels.push(x + " week" + (x > 1 ? "s" : "") + " ago");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
labels.push("");
|
labels.push("");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new Chartist.Line("#views-graph", {
|
new Chartist.Line("#views-graph", {
|
||||||
labels: labels,
|
labels: labels,
|
||||||
@@ -92,9 +98,13 @@
|
|||||||
series: [comments],
|
series: [comments],
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
data.domains[data.cd].viewsLast30Days = numberify(views.reduce(function(a, b) { return a + b; }, 0));
|
data.domains[data.cd].viewsLast30Days = numberify(views.reduce(function(a, b) {
|
||||||
data.domains[data.cd].commentsLast30Days = numberify(comments.reduce(function(a, b) { return a + b; }, 0));
|
return a + b;
|
||||||
|
}, 0));
|
||||||
|
data.domains[data.cd].commentsLast30Days = numberify(comments.reduce(function(a, b) {
|
||||||
|
return a + b;
|
||||||
|
}, 0));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Sets a vue.js field. Short for "vue set".
|
// Sets a vue.js field. Short for "vue set".
|
||||||
function vs(field, value) {
|
function vs(field, value) {
|
||||||
@@ -23,42 +26,42 @@
|
|||||||
"text": "Installation",
|
"text": "Installation",
|
||||||
"meaning": "Install Commento with HTML",
|
"meaning": "Install Commento with HTML",
|
||||||
"selected": false,
|
"selected": false,
|
||||||
"open": installationOpen,
|
"open": global.installationOpen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "general",
|
"id": "general",
|
||||||
"text": "Configure Domain",
|
"text": "Configure Domain",
|
||||||
"meaning": "Names, domains and the rest",
|
"meaning": "Names, domains and the rest",
|
||||||
"selected": false,
|
"selected": false,
|
||||||
"open": generalOpen,
|
"open": global.generalOpen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "moderation",
|
"id": "moderation",
|
||||||
"text": "Moderation Settings",
|
"text": "Moderation Settings",
|
||||||
"meaning": "Manage list of moderators",
|
"meaning": "Manage list of moderators",
|
||||||
"selected": false,
|
"selected": false,
|
||||||
"open": moderationOpen,
|
"open": global.moderationOpen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "statistics",
|
"id": "statistics",
|
||||||
"text": "View Activity",
|
"text": "View Activity",
|
||||||
"meaning": "Usage and comment statistics",
|
"meaning": "Usage and comment statistics",
|
||||||
"selected": false,
|
"selected": false,
|
||||||
"open": statisticsOpen,
|
"open": global.statisticsOpen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "import",
|
"id": "import",
|
||||||
"text": "Import Comments",
|
"text": "Import Comments",
|
||||||
"meaning": "Import from a different service",
|
"meaning": "Import from a different service",
|
||||||
"selected": false,
|
"selected": false,
|
||||||
"open": importOpen,
|
"open": global.importOpen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "danger",
|
"id": "danger",
|
||||||
"text": "Danger Zone",
|
"text": "Danger Zone",
|
||||||
"meaning": "Delete or freeze domain",
|
"meaning": "Delete or freeze domain",
|
||||||
"selected": false,
|
"selected": false,
|
||||||
"open": dangerOpen,
|
"open": global.dangerOpen,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -82,8 +85,9 @@
|
|||||||
data: reactiveData,
|
data: reactiveData,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (callback !== undefined)
|
if (callback !== undefined) {
|
||||||
callback();
|
callback();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Registers a given ID for a fade out after 5 seconds.
|
// Registers a given ID for a fade out after 5 seconds.
|
||||||
global.registerHide = function(id) {
|
global.registerHide = function(id) {
|
||||||
var el = $(id);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$(id).fadeOut("fast");
|
$(id).fadeOut("fast");
|
||||||
}, 5000);
|
}, 5000);
|
||||||
@@ -28,4 +29,4 @@
|
|||||||
global.showGlobalMessage("#global-ok", text);
|
global.showGlobalMessage("#global-ok", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Talks to the API and sends an reset email.
|
// Talks to the API and sends an reset email.
|
||||||
global.sendResetHex = function() {
|
global.sendResetHex = function() {
|
||||||
var all_ok = global.unfilledMark(["#email"], function(el) {
|
var allOk = global.unfilledMark(["#email"], function(el) {
|
||||||
el.css("border-bottom", "1px solid red");
|
el.css("border-bottom", "1px solid red");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!all_ok) {
|
if (!allOk) {
|
||||||
global.textSet("#err", "Please make sure all fields are filled.");
|
global.textSet("#err", "Please make sure all fields are filled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -16,7 +19,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
global.buttonDisable("#reset-button");
|
global.buttonDisable("#reset-button");
|
||||||
global.post(global.commentoOrigin + "/api/owner/send-reset-hex", json, function(resp) {
|
global.post(global.origin + "/api/owner/send-reset-hex", json, function(resp) {
|
||||||
global.buttonEnable("#reset-button");
|
global.buttonEnable("#reset-button");
|
||||||
|
|
||||||
global.textSet("#err", "");
|
global.textSet("#err", "");
|
||||||
@@ -30,4 +33,4 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,7 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Performs a JSON POST request to the given url with the given data and
|
// Performs a JSON POST request to the given url with the given data and
|
||||||
// calls the callback function with the JSON response.
|
// calls the callback function with the JSON response.
|
||||||
@@ -28,4 +31,4 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
4
frontend/js/jquery.js
vendored
4
frontend/js/jquery.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,13 +1,15 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
// Shows messages produced from email confirmation attempts.
|
// Shows messages produced from email confirmation attempts.
|
||||||
function displayConfirmedEmail() {
|
function displayConfirmedEmail() {
|
||||||
var confirmed = global.paramGet("confirmed");
|
var confirmed = global.paramGet("confirmed");
|
||||||
|
|
||||||
if (confirmed == "true") {
|
if (confirmed === "true") {
|
||||||
$("#msg").html("Successfully confirmed! Login to continue.")
|
$("#msg").html("Successfully confirmed! Login to continue.")
|
||||||
}
|
} else if (confirmed === "false") {
|
||||||
else if (confirmed == "false") {
|
|
||||||
$("#err").html("That link has expired.")
|
$("#err").html("That link has expired.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,18 +17,18 @@
|
|||||||
|
|
||||||
// Shows messages produced from password reset attempts.
|
// Shows messages produced from password reset attempts.
|
||||||
function displayChangedPassword() {
|
function displayChangedPassword() {
|
||||||
var changed = paramGet("changed");
|
var changed = global.paramGet("changed");
|
||||||
|
|
||||||
if (changed == "true") {
|
if (changed === "true") {
|
||||||
$("#msg").html("Password changed successfully! Login to continue.")
|
$("#msg").html("Password changed successfully! Login to continue.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shows messages produced from completed signups.
|
// Shows messages produced from completed signups.
|
||||||
function displaySignedUp() {
|
function displaySignedUp() {
|
||||||
var signedUp = paramGet("signedUp");
|
var signedUp = global.paramGet("signedUp");
|
||||||
|
|
||||||
if (signedUp == "true") {
|
if (signedUp === "true") {
|
||||||
$("#msg").html("Registration successful! Login to continue.")
|
$("#msg").html("Registration successful! Login to continue.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,11 +44,11 @@
|
|||||||
|
|
||||||
// Logs the user in and redirects to the dashboard.
|
// Logs the user in and redirects to the dashboard.
|
||||||
global.login = function() {
|
global.login = function() {
|
||||||
var all_ok = global.unfilledMark(["#email", "#password"], function(el) {
|
var allOk = global.unfilledMark(["#email", "#password"], function(el) {
|
||||||
el.css("border-bottom", "1px solid red");
|
el.css("border-bottom", "1px solid red");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!all_ok) {
|
if (!allOk) {
|
||||||
global.textSet("#err", "Please make sure all fields are filled");
|
global.textSet("#err", "Please make sure all fields are filled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -57,7 +59,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
global.buttonDisable("#login-button");
|
global.buttonDisable("#login-button");
|
||||||
global.post(global.commentoOrigin + "/api/owner/login", json, function(resp) {
|
global.post(global.origin + "/api/owner/login", json, function(resp) {
|
||||||
global.buttonEnable("#login-button");
|
global.buttonEnable("#login-button");
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
@@ -66,8 +68,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
global.cookieSet("commentoOwnerToken", resp.ownerToken);
|
global.cookieSet("commentoOwnerToken", resp.ownerToken);
|
||||||
document.location = global.commentoOrigin + "/dashboard";
|
document.location = global.origin + "/dashboard";
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
global.logout = function() {
|
global.logout = function() {
|
||||||
global.cookieDelete("commentoOwnerToken");
|
global.cookieDelete("commentoOwnerToken");
|
||||||
document.location = global.commentoOrigin + "/login";
|
document.location = global.origin + "/login";
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
global.resetPassword = function() {
|
global.resetPassword = function() {
|
||||||
var all_ok = global.unfilledMark(["#password", "#password2"], function(el) {
|
var allOk = global.unfilledMark(["#password", "#password2"], function(el) {
|
||||||
el.css("border-bottom", "1px solid red");
|
el.css("border-bottom", "1px solid red");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!all_ok) {
|
if (!allOk) {
|
||||||
global.textSet("#err", "Please make sure all fields are filled.");
|
global.textSet("#err", "Please make sure all fields are filled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($("#password").val() != $("#password2").val()) {
|
if ($("#password").val() !== $("#password2").val()) {
|
||||||
global.textSet("#err", "The two passwords do not match.");
|
global.textSet("#err", "The two passwords do not match.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
global.buttonDisable("#reset-button");
|
global.buttonDisable("#reset-button");
|
||||||
global.post(global.commentoOrigin + "/api/owner/reset-password", json, function(resp) {
|
global.post(global.origin + "/api/owner/reset-password", json, function(resp) {
|
||||||
global.buttonEnable("#reset-button");
|
global.buttonEnable("#reset-button");
|
||||||
|
|
||||||
global.textSet("#err", "");
|
global.textSet("#err", "");
|
||||||
@@ -30,8 +31,8 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
document.location = global.commentoOrigin + "/login?changed=true";
|
document.location = global.origin + "/login?changed=true";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// Get self details.
|
// Get self details.
|
||||||
global.selfGet = function(callback) {
|
global.selfGet = function(callback) {
|
||||||
@@ -7,14 +8,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (json.ownerToken === undefined) {
|
if (json.ownerToken === undefined) {
|
||||||
document.location = global.commentoOrigin + "/login";
|
document.location = global.origin + "/login";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
global.post(global.commentoOrigin + "/api/owner/self", json, function(resp) {
|
global.post(global.origin + "/api/owner/self", json, function(resp) {
|
||||||
if (!resp.success || !resp.loggedIn) {
|
if (!resp.success || !resp.loggedIn) {
|
||||||
global.cookieDelete("commentoOwnerToken");
|
global.cookieDelete("commentoOwnerToken");
|
||||||
document.location = global.commentoOrigin + "/login";
|
document.location = global.origin + "/login";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,4 +24,4 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
}(window, document));
|
}(window.commento, document));
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict"
|
||||||
|
|
||||||
// Signs up the user and redirects to either the login page or the email
|
// Signs up the user and redirects to either the login page or the email
|
||||||
// confirmation, depending on whether or not SMTP is configured in the
|
// confirmation, depending on whether or not SMTP is configured in the
|
||||||
// backend.
|
// backend.
|
||||||
global.signup = function() {
|
global.signup = function() {
|
||||||
if ($("#password").val() != $("#password2").val()) {
|
if ($("#password").val() !== $("#password2").val()) {
|
||||||
global.textSet("#err", "The two passwords don't match");
|
global.textSet("#err", "The two passwords don't match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var all_ok = unfilledMark(["#email", "#name", "#password", "#password2"], function(el) {
|
var allOk = global.unfilledMark(["#email", "#name", "#password", "#password2"], function(el) {
|
||||||
el.css("border-bottom", "1px solid red");
|
el.css("border-bottom", "1px solid red");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!all_ok) {
|
if (!allOk) {
|
||||||
global.textSet("#err", "Please make sure all fields are filled");
|
global.textSet("#err", "Please make sure all fields are filled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
global.buttonDisable("#signup-button");
|
global.buttonDisable("#signup-button");
|
||||||
post(global.commentoOrigin + "/api/owner/new", json, function(resp) {
|
global.post(global.origin + "/api/owner/new", json, function(resp) {
|
||||||
global.buttonEnable("#signup-button")
|
global.buttonEnable("#signup-button")
|
||||||
|
|
||||||
if (!resp.success) {
|
if (!resp.success) {
|
||||||
@@ -33,11 +34,12 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.confirmEmail)
|
if (resp.confirmEmail) {
|
||||||
document.location = global.commentoOrigin + "/confirm-email";
|
document.locatidocumenton = global.origin + "/confirm-email";
|
||||||
else
|
} else {
|
||||||
document.location = global.commentoOrigin + "/login?signedUp=true";
|
document.location = global.origin + "/login?signedUp=true";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
} (window, document));
|
} (window.commento, document));
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
(function (global, document) {
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// Gets a GET parameter in the current URL.
|
// Gets a GET parameter in the current URL.
|
||||||
global.paramGet = function(param) {
|
global.paramGet = function(param) {
|
||||||
var pageURL = decodeURIComponent(window.location.search.substring(1));
|
var pageURL = decodeURIComponent(window.location.search.substring(1));
|
||||||
var urlVariables = pageURL.split('&');
|
var urlVariables = pageURL.split("&");
|
||||||
|
|
||||||
for (var i = 0; i < urlVariables.length; i++) {
|
for (var i = 0; i < urlVariables.length; i++) {
|
||||||
var paramURL = urlVariables[i].split('=');
|
var paramURL = urlVariables[i].split("=");
|
||||||
if (paramURL[0] === param)
|
if (paramURL[0] === param) {
|
||||||
return paramURL[1] === undefined ? true : paramURL[1];
|
return paramURL[1] === undefined ? true : paramURL[1];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -42,16 +44,16 @@
|
|||||||
// Given an array of input IDs, this function calls a callback function with
|
// Given an array of input IDs, this function calls a callback function with
|
||||||
// the first unfilled ID.
|
// the first unfilled ID.
|
||||||
global.unfilledMark = function(fields, callback) {
|
global.unfilledMark = function(fields, callback) {
|
||||||
var all_ok = true;
|
var allOk = true;
|
||||||
|
|
||||||
for (var i = 0; i < fields.length; i++) {
|
for (var i = 0; i < fields.length; i++) {
|
||||||
var el = $(fields[i]);
|
var el = $(fields[i]);
|
||||||
if (el.val() == "") {
|
if (el.val() === "") {
|
||||||
callback(el);
|
callback(el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return all_ok;
|
return allOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -59,8 +61,9 @@
|
|||||||
global.cookieGet = function(name) {
|
global.cookieGet = function(name) {
|
||||||
var c = "; " + document.cookie;
|
var c = "; " + document.cookie;
|
||||||
var x = c.split("; " + name + "=");
|
var x = c.split("; " + name + "=");
|
||||||
if (x.length == 2)
|
if (x.length === 2) {
|
||||||
return x.pop().split(";").shift();
|
return x.pop().split(";").shift();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -72,8 +75,9 @@
|
|||||||
expires = "; expires=" + date.toUTCString();
|
expires = "; expires=" + date.toUTCString();
|
||||||
|
|
||||||
var cookieString = name + "=" + value + expires + "; path=/";
|
var cookieString = name + "=" + value + expires + "; path=/";
|
||||||
if (/^https:\/\//i.test(commentoOrigin))
|
if (/^https:\/\//i.test(origin)) {
|
||||||
cookieString += "; secure";
|
cookieString += "; secure";
|
||||||
|
}
|
||||||
|
|
||||||
document.cookie = cookieString;
|
document.cookie = cookieString;
|
||||||
}
|
}
|
||||||
@@ -81,7 +85,7 @@
|
|||||||
|
|
||||||
// Deletes a cookie.
|
// Deletes a cookie.
|
||||||
global.cookieDelete = function(name) {
|
global.cookieDelete = function(name) {
|
||||||
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,29 +94,35 @@
|
|||||||
var seconds = Math.floor((new Date() - date) / 1000);
|
var seconds = Math.floor((new Date() - date) / 1000);
|
||||||
var interval = Math.floor(seconds / 31536000);
|
var interval = Math.floor(seconds / 31536000);
|
||||||
|
|
||||||
if (interval > 1)
|
if (interval > 1) {
|
||||||
return interval + " years ago";
|
return interval + " years ago";
|
||||||
|
|
||||||
interval = Math.floor(seconds / 2592000);
|
|
||||||
if (interval > 1)
|
|
||||||
return interval + " months ago";
|
|
||||||
|
|
||||||
interval = Math.floor(seconds / 86400);
|
|
||||||
if (interval > 1)
|
|
||||||
return interval + " days ago";
|
|
||||||
|
|
||||||
interval = Math.floor(seconds / 3600);
|
|
||||||
if (interval > 1)
|
|
||||||
return interval + " hours ago";
|
|
||||||
|
|
||||||
interval = Math.floor(seconds / 60);
|
|
||||||
if (interval > 1)
|
|
||||||
return interval + " minutes ago";
|
|
||||||
|
|
||||||
if (seconds > 5)
|
|
||||||
return Math.floor(seconds) + " seconds ago";
|
|
||||||
else
|
|
||||||
return "just now";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} (window, document));
|
interval = Math.floor(seconds / 2592000);
|
||||||
|
if (interval > 1) {
|
||||||
|
return interval + " months ago";
|
||||||
|
}
|
||||||
|
|
||||||
|
interval = Math.floor(seconds / 86400);
|
||||||
|
if (interval > 1) {
|
||||||
|
return interval + " days ago";
|
||||||
|
}
|
||||||
|
|
||||||
|
interval = Math.floor(seconds / 3600);
|
||||||
|
if (interval > 1) {
|
||||||
|
return interval + " hours ago";
|
||||||
|
}
|
||||||
|
|
||||||
|
interval = Math.floor(seconds / 60);
|
||||||
|
if (interval > 1) {
|
||||||
|
return interval + " minutes ago";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seconds > 5) {
|
||||||
|
return Math.floor(seconds) + " seconds ago";
|
||||||
|
} else {
|
||||||
|
return "just now";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} (window.commento, document));
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window.loggedInRedirect();
|
window.commento.loggedInRedirect();
|
||||||
window.prefillEmail();
|
window.commento.prefillEmail();
|
||||||
window.displayMessages();
|
window.commento.displayMessages();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<div class="err" id="err"></div>
|
<div class="err" id="err"></div>
|
||||||
<div class="msg" id="msg"></div>
|
<div class="msg" id="msg"></div>
|
||||||
|
|
||||||
<button id="button" class="button" onclick="window.login()">Login</button>
|
<button id="button" class="button" onclick="window.commento.login()">Login</button>
|
||||||
|
|
||||||
<a class="link" href="[[[.Origin]]]/forgot">Trouble logging in? Reset your password.</a>
|
<a class="link" href="[[[.Origin]]]/forgot">Trouble logging in? Reset your password.</a>
|
||||||
<a class="link" href="[[[.Origin]]]/signup">Don't have an account yet? Sign up.</a>
|
<a class="link" href="[[[.Origin]]]/signup">Don't have an account yet? Sign up.</a>
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.onload = window.logout;
|
window.onload = window.commento.logout;
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
33
frontend/package.json
Normal file
33
frontend/package.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "commento",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"repository": "git@gitlab.com:commento/commento.git",
|
||||||
|
"author": "Adhityaa <c.adhityaa@gmail.com> Anton Linevych anton@linevich.net",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"chartist": "0.11.0",
|
||||||
|
"fixmyjs": "2.0.0",
|
||||||
|
"gulp": "3.9.1",
|
||||||
|
"gulp-clean-css": "3.9.4",
|
||||||
|
"gulp-concat": "2.6.1",
|
||||||
|
"gulp-eslint": "5.0.0",
|
||||||
|
"gulp-html-minifier": "0.1.8",
|
||||||
|
"gulp-rename": "1.3.0",
|
||||||
|
"gulp-sass": "4.0.1",
|
||||||
|
"gulp-sourcemaps": "2.6.4",
|
||||||
|
"gulp-uglify": "3.0.0",
|
||||||
|
"highlightjs": "9.10.0",
|
||||||
|
"html-minifier": "3.5.7",
|
||||||
|
"jquery": "3.2.1",
|
||||||
|
"natives": "^1.1.6",
|
||||||
|
"normalize-scss": "7.0.1",
|
||||||
|
"sass": "1.5.1",
|
||||||
|
"uglify-js": "3.4.1",
|
||||||
|
"vue": "2.5.16"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"eslint": "^5.10.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<div class="err" id="err"></div>
|
<div class="err" id="err"></div>
|
||||||
<div class="msg" id="msg"></div>
|
<div class="msg" id="msg"></div>
|
||||||
<button id="reset-button" class="button" onclick="resetPassword()">Reset Password</button>
|
<button id="reset-button" class="button" onclick="window.commento.resetPassword()">Reset Password</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,20 @@
|
|||||||
background: $green-7;
|
background: $green-7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.commento-option-sticky,
|
||||||
|
.commento-option-unsticky {
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
@include mask-image('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8"?><svg enable-background="new 0 0 487.222 487.222" version="1.1" viewBox="0 0 487.22 487.22" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m486.55 186.81c-1.6-4.9-5.8-8.4-10.9-9.2l-152-21.6-68.4-137.5c-2.3-4.6-7-7.5-12.1-7.5s-9.8 2.9-12.1 7.6l-67.5 137.9-152 22.6c-5.1 0.8-9.3 4.3-10.9 9.2s-0.2 10.3 3.5 13.8l110.3 106.9-25.5 151.4c-0.9 5.1 1.2 10.2 5.4 13.2 2.3 1.7 5.1 2.6 7.9 2.6 2.2 0 4.3-0.5 6.3-1.6l135.7-71.9 136.1 71.1c2 1 4.1 1.5 6.2 1.5 7.4 0 13.5-6.1 13.5-13.5 0-1.1-0.1-2.1-0.4-3.1l-26.3-150.5 109.6-107.5c3.9-3.6 5.2-9 3.6-13.9zm-137 107.1c-3.2 3.1-4.6 7.6-3.8 12l22.9 131.3-118.2-61.7c-3.9-2.1-8.6-2-12.6 0l-117.8 62.4 22.1-131.5c0.7-4.4-0.7-8.8-3.9-11.9l-95.6-92.8 131.9-19.6c4.4-0.7 8.2-3.4 10.1-7.4l58.6-119.7 59.4 119.4c2 4 5.8 6.7 10.2 7.4l132 18.8-95.3 93.3z" fill="%231e2127"/></svg>');
|
||||||
|
margin: 12px 6px 12px 6px;
|
||||||
|
background: $gray-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.commento-option-unsticky {
|
||||||
|
@include mask-image('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8"?><svg viewBox="0 0 487.22 487.22" xmlns="http://www.w3.org/2000/svg"><g><title>background</title><rect x="-1" y="-1" fill="none"/></g><g><title>Layer 1</title><path d="m486.55 186.81c-1.6-4.9-5.8-8.4-10.9-9.2l-152-21.6-68.4-137.5c-2.3-4.6-7-7.5-12.1-7.5s-9.8 2.9-12.1 7.6l-67.5 137.9-152 22.6c-5.1 0.8-9.3 4.3-10.9 9.2s-0.2 10.3 3.5 13.8l110.3 106.9-25.5 151.4c-0.9 5.1 1.2 10.2 5.4 13.2 2.3 1.7 5.1 2.6 7.9 2.6 2.2 0 4.3-0.5 6.3-1.6l135.7-71.9 136.1 71.1c2 1 4.1 1.5 6.2 1.5 7.4 0 13.5-6.1 13.5-13.5 0-1.1-0.1-2.1-0.4-3.1l-26.3-150.5 109.6-107.5c3.9-3.6 5.2-9 3.6-13.9z" fill="%231e2127"/></g></svg>');
|
||||||
|
background: $yellow-7;
|
||||||
|
}
|
||||||
|
|
||||||
.commento-option-button:focus {
|
.commento-option-button:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ textarea::placeholder {
|
|||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
line-height: 80px;
|
line-height: 110px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -28,7 +28,7 @@ textarea {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
outline: none;
|
outline: none;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
min-height: 100px;
|
min-height: 130px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ textarea {
|
|||||||
|
|
||||||
.commento-account-buttons-question {
|
.commento-account-buttons-question {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.5rem;
|
top: 10px;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -124,9 +124,14 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.commento-anonymous-button {
|
.commento-anonymous-button {
|
||||||
background: #096fa6;
|
display: block;
|
||||||
text-transform: uppercase;
|
color: $blue-6;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: 12px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-blurred-textarea {
|
.commento-blurred-textarea {
|
||||||
@@ -152,18 +157,24 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.commento-create-button {
|
.commento-create-button {
|
||||||
width: 120px;
|
width: 150px;
|
||||||
background: $pink-9;
|
background: $pink-9;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-login-button {
|
.commento-login-button {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
background: $cyan-9;
|
background: $cyan-9;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-submit-button {
|
.commento-submit-button {
|
||||||
float: right;
|
float: right;
|
||||||
background: $indigo-7;
|
background: $indigo-7;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-approve-button {
|
.commento-approve-button {
|
||||||
@@ -177,18 +188,3 @@ textarea {
|
|||||||
.commento-button-margin {
|
.commento-button-margin {
|
||||||
padding-bottom: 60px;
|
padding-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-mod-tools-lock-button {
|
|
||||||
color: $gray-6;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 12px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
margin-left: 12px;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commento-mod-tools-lock-button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.commento-login-link {
|
.commento-login-link {
|
||||||
font-size: 15px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro');
|
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700');
|
||||||
|
|
||||||
.commento-root-min-height {
|
.commento-root-min-height {
|
||||||
min-height: 350px;
|
min-height: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-root {
|
.commento-root {
|
||||||
font-family: "Source Sans Pro", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
overflow-x: hidden;
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: "Source Sans Pro", "Segoe UI", "Roboto", "Helvetica Neue", sans-serif;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: #50596c;
|
color: #50596c;
|
||||||
overflow-x: hidden;
|
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
padding: 8px;
|
}
|
||||||
|
|
||||||
@import "colors-main.scss";
|
@import "colors-main.scss";
|
||||||
@import "common-main.scss";
|
@import "common-main.scss";
|
||||||
@@ -41,19 +44,30 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: $red-7;
|
color: $red-7;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-mod-tools {
|
.commento-mod-tools {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: $gray-7;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 12px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-mod-tools::before {
|
.commento-mod-tools::before {
|
||||||
content: "Moderators";
|
content: "Moderator Tools";
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: $indigo-8;
|
color: $indigo-8;
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-moderation-notice {
|
.commento-moderation-notice {
|
||||||
@@ -62,17 +76,17 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: $orange-7;
|
color: $orange-7;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-dark-card {
|
.commento-dark-card {
|
||||||
background: $blue-1;
|
background: $yellow-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-avatar {
|
.commento-avatar {
|
||||||
width: 34px;
|
width: 38px;
|
||||||
height: 34px;
|
height: 38px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -81,8 +95,7 @@
|
|||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
border: 1px solid #fff;
|
border: 0px transparent;
|
||||||
box-shadow: 0px 0px 0px 2px #f00;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-avatar-img {
|
.commento-avatar-img {
|
||||||
@@ -111,7 +124,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.commento-name {
|
.commento-name {
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #555;
|
color: #555;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -124,6 +137,17 @@
|
|||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.commento-flagged::after {
|
||||||
|
content: "Flagged";
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 10px;
|
||||||
|
background: $red-7;
|
||||||
|
color: white;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding: 2px 6px 2px 6px;
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.commento-subtitle {
|
.commento-subtitle {
|
||||||
display: block;
|
display: block;
|
||||||
color: #999;
|
color: #999;
|
||||||
@@ -131,13 +155,20 @@
|
|||||||
margin-left: 48px;
|
margin-left: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-score {
|
.commento-timeago {
|
||||||
display: inline;
|
display: inline;
|
||||||
color: #999;
|
color: #888;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commento-score::before {
|
.commento-score {
|
||||||
|
display: inline;
|
||||||
|
color: #888;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.commento-timeago::before {
|
||||||
content: "\00a0 \00a0 \00b7 \00a0 \00a0";
|
content: "\00a0 \00a0 \00b7 \00a0 \00a0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +186,16 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.commento-options-mobile {
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.commento-options-clearfix {
|
||||||
|
height: 38px;
|
||||||
|
width: 1px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.commento-moderation {
|
.commento-moderation {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window.loggedInRedirect();
|
window.commento.loggedInRedirect();
|
||||||
window.prefillEmail();
|
window.commento.prefillEmail();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
<p class="cent">
|
<p class="cent">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button id="signup-button" class="button" onclick="window.signup()">Sign up</button>
|
<button id="signup-button" class="button" onclick="window.commento.signup()">Sign up</button>
|
||||||
|
|
||||||
<a class="link" href="[[[.Origin]]]/login">Already have an account? Login instead.</a>
|
<a class="link" href="[[[.Origin]]]/login">Already have an account? Login instead.</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
4501
frontend/yarn.lock
Normal file
4501
frontend/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
binary_name=commento-ce
|
binary_name=commento
|
||||||
|
|
||||||
trap ctrl_c INT
|
trap ctrl_c INT
|
||||||
ctrl_c() {
|
ctrl_c() {
|
||||||
@@ -9,10 +9,12 @@ ctrl_c() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version=devel
|
||||||
|
|
||||||
binary_pid=
|
binary_pid=
|
||||||
if make -j$(($(nproc) + 1)); then
|
if make $version -j$(($(nproc) + 1)); then
|
||||||
source devel.env
|
source devel.env
|
||||||
cd build/devel
|
cd build/$version
|
||||||
./$binary_name &
|
./$binary_name &
|
||||||
binary_pid=$!
|
binary_pid=$!
|
||||||
cd ../../
|
cd ../../
|
||||||
@@ -50,9 +52,9 @@ while true; do
|
|||||||
wait $binary_pid
|
wait $binary_pid
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if make -j$(($(nproc) + 1)); then
|
if make $version -j$(($(nproc) + 1)); then
|
||||||
source devel.env
|
source devel.env
|
||||||
cd build/devel
|
cd build/$version
|
||||||
./$binary_name &
|
./$binary_name &
|
||||||
binary_pid=$!
|
binary_pid=$!
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|||||||
0
scripts/check-dco
Normal file → Executable file
0
scripts/check-dco
Normal file → Executable file
17
scripts/gitlab-ci-build-prescript
Normal file
17
scripts/gitlab-ci-build-prescript
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
mkdir -p /go/src /go/bin /go/pkg
|
||||||
|
ln -s $CI_PROJECT_DIR /go/src/$CI_PROJECT_NAME
|
||||||
|
|
||||||
|
apt update
|
||||||
|
apt install -y curl gnupg git make golang python
|
||||||
|
export GOPATH=/go
|
||||||
|
export PATH=$PATH:/go/bin
|
||||||
|
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||||
|
|
||||||
|
curl -sL https://deb.nodesource.com/setup_10.x | bash -
|
||||||
|
apt install -y nodejs
|
||||||
|
npm install -g yarn@1.10.0
|
||||||
|
|
||||||
|
apt install -y python python-pip
|
||||||
|
pip install awscli
|
||||||
Reference in New Issue
Block a user