mirror of
https://github.com/arnaucube/decentralized-blogging-platform.git
synced 2026-02-06 19:06:45 +01:00
signup and login working
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
keys
|
||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# decentralized-blogging-platform
|
||||
|
||||
Decentralized blogging platform, using IPFS
|
||||
|
||||
|
||||
|
||||
### Instructions
|
||||
|
||||
- Need to add:
|
||||
```
|
||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
|
||||
```
|
||||
in order to allow access to IPFS from the app.
|
||||
|
||||
- Start the IPFS daemon
|
||||
```
|
||||
ipfs daemon
|
||||
```
|
||||
96
RESTfunctions.go
Normal file
96
RESTfunctions.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id bson.ObjectId `json:"id" bson:"_id,omitempty"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
func Index(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "clientApp")
|
||||
}
|
||||
|
||||
func Signup(w http.ResponseWriter, r *http.Request) {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
var user User
|
||||
err := decoder.Decode(&user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
fmt.Print("user signup: ")
|
||||
fmt.Println(user.Username)
|
||||
|
||||
//save the new project to mongodb
|
||||
rUser := User{}
|
||||
err = userCollection.Find(bson.M{"email": user.Email}).One(&rUser)
|
||||
if err != nil {
|
||||
//user not exists
|
||||
err = userCollection.Insert(user)
|
||||
err = userCollection.Find(bson.M{"email": user.Email}).One(&user)
|
||||
} else {
|
||||
//user exists
|
||||
http.Error(w, "user already registered", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(user.Username)
|
||||
jResp, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Fprintln(w, string(jResp))
|
||||
}
|
||||
|
||||
func Login(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
var user User
|
||||
err := decoder.Decode(&user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Body.Close()
|
||||
//TODO check if the user password exists in the database
|
||||
|
||||
fmt.Print("user login: ")
|
||||
fmt.Println(user)
|
||||
|
||||
//save the new project to mongodb
|
||||
rUser := User{}
|
||||
err = userCollection.Find(bson.M{"email": user.Email}).One(&rUser)
|
||||
if err != nil {
|
||||
http.Error(w, "error login, email not foun", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
//user exists, check password
|
||||
if user.Password != rUser.Password {
|
||||
http.Error(w, "error login, password not match", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := newToken()
|
||||
check(err)
|
||||
rUser.Token = token
|
||||
|
||||
//update with the token
|
||||
err = userCollection.Update(bson.M{"_id": rUser.Id}, rUser)
|
||||
check(err)
|
||||
|
||||
jResp, err := json.Marshal(rUser)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Fprintln(w, string(jResp))
|
||||
}
|
||||
8
config.json
Executable file
8
config.json
Executable file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"apiport": "3000",
|
||||
"webport": "8081",
|
||||
"mongodb": {
|
||||
"ip": "127.0.0.1:27017",
|
||||
"database": "decentralized-blogging-platform"
|
||||
}
|
||||
}
|
||||
15
errors.go
Executable file
15
errors.go
Executable file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
_, fn, line, _ := runtime.Caller(1)
|
||||
log.Println(line)
|
||||
log.Println(fn)
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
12
hash.go
Normal file
12
hash.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
func hash(s string) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(s))
|
||||
return base64.URLEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
19
log.go
Executable file
19
log.go
Executable file
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func savelog() {
|
||||
timeS := time.Now().String()
|
||||
_ = os.Mkdir("logs", os.ModePerm)
|
||||
logFile, err := os.OpenFile("logs/log-"+timeS+".log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mw := io.MultiWriter(os.Stdout, logFile)
|
||||
log.SetOutput(mw)
|
||||
}
|
||||
51
main.go
Normal file
51
main.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/gorilla/handlers"
|
||||
mgo "gopkg.in/mgo.v2"
|
||||
)
|
||||
|
||||
const keysDir = "keys"
|
||||
const keysize = 2048
|
||||
const hashize = 1536
|
||||
|
||||
var userCollection *mgo.Collection
|
||||
|
||||
func main() {
|
||||
color.Blue("Starting ipfs-ai-models-market")
|
||||
|
||||
readConfig("config.json")
|
||||
fmt.Println(config)
|
||||
|
||||
initializeToken()
|
||||
|
||||
//mongodb
|
||||
session, err := getSession()
|
||||
check(err)
|
||||
userCollection = getCollection(session, "users")
|
||||
|
||||
//run thw webserver
|
||||
go GUI()
|
||||
|
||||
//run API
|
||||
log.Println("api server running")
|
||||
log.Print("port: ")
|
||||
log.Println(config.APIPort)
|
||||
router := NewRouter()
|
||||
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"})
|
||||
originsOk := handlers.AllowedOrigins([]string{"*"})
|
||||
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
|
||||
log.Fatal(http.ListenAndServe(":"+config.APIPort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))
|
||||
}
|
||||
|
||||
func GUI() {
|
||||
//here, run webserver
|
||||
log.Println("webserver in port " + config.WebPort)
|
||||
http.Handle("/", http.FileServer(http.Dir("./webapp")))
|
||||
http.ListenAndServe(":"+config.WebPort, nil)
|
||||
}
|
||||
26
mongoOperations.go
Executable file
26
mongoOperations.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
mgo "gopkg.in/mgo.v2"
|
||||
)
|
||||
|
||||
func getSession() (*mgo.Session, error) {
|
||||
session, err := mgo.Dial("mongodb://" + config.Mongodb.IP)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
//defer session.Close()
|
||||
|
||||
// Optional. Switch the session to a monotonic behavior.
|
||||
session.SetMode(mgo.Monotonic, true)
|
||||
|
||||
// Optional. Switch the session to a monotonic behavior.
|
||||
session.SetMode(mgo.Monotonic, true)
|
||||
|
||||
return session, err
|
||||
}
|
||||
func getCollection(session *mgo.Session, collection string) *mgo.Collection {
|
||||
|
||||
c := session.DB(config.Mongodb.Database).C(collection)
|
||||
return c
|
||||
}
|
||||
26
readConfig.go
Executable file
26
readConfig.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
//Config reads the config
|
||||
type Config struct {
|
||||
APIPort string `json:"apiport"`
|
||||
WebPort string `json:"webport"`
|
||||
Mongodb MongoConfig `json:"mongodb"`
|
||||
}
|
||||
type MongoConfig struct {
|
||||
IP string `json:"ip"`
|
||||
Database string `json:"database"`
|
||||
}
|
||||
|
||||
var config Config
|
||||
|
||||
func readConfig(path string) {
|
||||
file, err := ioutil.ReadFile(path)
|
||||
check(err)
|
||||
content := string(file)
|
||||
json.Unmarshal([]byte(content), &config)
|
||||
}
|
||||
47
restConfig.go
Executable file
47
restConfig.go
Executable file
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type Route struct {
|
||||
Name string
|
||||
Method string
|
||||
Pattern string
|
||||
HandlerFunc http.HandlerFunc
|
||||
}
|
||||
|
||||
func Logger(inner http.Handler, name string) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
start := time.Now()
|
||||
|
||||
inner.ServeHTTP(w, r)
|
||||
|
||||
log.Printf(
|
||||
"%s\t%s\t%s\t%s",
|
||||
r.Method,
|
||||
r.RequestURI,
|
||||
name,
|
||||
time.Since(start),
|
||||
)
|
||||
})
|
||||
}
|
||||
func NewRouter() *mux.Router {
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
for _, route := range routes {
|
||||
var handler http.Handler
|
||||
handler = route.HandlerFunc
|
||||
handler = Logger(handler, route.Name)
|
||||
|
||||
router.
|
||||
Methods(route.Method).
|
||||
Path(route.Pattern).
|
||||
Name(route.Name).
|
||||
Handler(handler)
|
||||
}
|
||||
return router
|
||||
}
|
||||
24
restRoutes.go
Executable file
24
restRoutes.go
Executable file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
type Routes []Route
|
||||
|
||||
var routes = Routes{
|
||||
Route{
|
||||
"Index",
|
||||
"GET",
|
||||
"/",
|
||||
Index,
|
||||
},
|
||||
Route{
|
||||
"Signup",
|
||||
"POST",
|
||||
"/signup",
|
||||
Signup,
|
||||
},
|
||||
Route{
|
||||
"Login",
|
||||
"POST",
|
||||
"/login",
|
||||
Login,
|
||||
},
|
||||
}
|
||||
49
tokens.go
Normal file
49
tokens.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const (
|
||||
signingKey = "this is the secret signing key"
|
||||
)
|
||||
|
||||
var createdToken string
|
||||
|
||||
func initializeToken() {
|
||||
var err error
|
||||
createdToken, err = newToken()
|
||||
if err != nil {
|
||||
fmt.Println("Creating token failed")
|
||||
}
|
||||
}
|
||||
|
||||
func newToken() (string, error) {
|
||||
signingKeyB := []byte(signingKey)
|
||||
// Create the token
|
||||
token := jwt.New(jwt.SigningMethodHS256)
|
||||
// Set some claims
|
||||
claims := make(jwt.MapClaims)
|
||||
claims["foo"] = "bar"
|
||||
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
|
||||
token.Claims = claims
|
||||
|
||||
// Sign and get the complete encoded token as a string
|
||||
tokenString, err := token.SignedString(signingKeyB)
|
||||
return tokenString, err
|
||||
}
|
||||
|
||||
func parseToken(myToken string, myKey string) {
|
||||
token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(myKey), nil
|
||||
})
|
||||
|
||||
if err == nil && token.Valid {
|
||||
fmt.Println("Your token is valid. I like your style.")
|
||||
} else {
|
||||
fmt.Println("This token is terrible! I cannot accept this.")
|
||||
}
|
||||
}
|
||||
5
webapp/.gitignore
vendored
Normal file
5
webapp/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
bower_components
|
||||
node_modules
|
||||
package-lock.json
|
||||
keys
|
||||
*.pem
|
||||
88
webapp/app.js
Normal file
88
webapp/app.js
Normal file
@@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
var apiurl = "http://127.0.0.1:3000/";
|
||||
|
||||
angular.module('app', [
|
||||
'ngRoute',
|
||||
'ngMessages',
|
||||
'toastr',
|
||||
'chart.js',
|
||||
'app.navbar',
|
||||
'app.signup',
|
||||
'app.login',
|
||||
'app.main',
|
||||
'app.newmodel',
|
||||
'app.profile'
|
||||
]).
|
||||
config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
|
||||
$locationProvider.hashPrefix('!');
|
||||
/*$routeProvider.otherwise({
|
||||
redirectTo: '/main'
|
||||
});*/
|
||||
|
||||
if((localStorage.getItem('dblog_user')))
|
||||
{
|
||||
console.log(window.location.hash);
|
||||
if((window.location.hash==='#!/login')||(window.location.hash==='#!/signup'))
|
||||
{
|
||||
window.location='#!/main';
|
||||
}
|
||||
|
||||
$routeProvider.otherwise({redirectTo: '/main'});
|
||||
}else{
|
||||
if((window.location!=='#!/login')||(window.location!=='#!/signup')||(window.location!=='#!/main'))
|
||||
{
|
||||
console.log('app, user no logged');
|
||||
|
||||
localStorage.removeItem('dblog_user');
|
||||
localStorage.removeItem('dblog_user');
|
||||
window.location='#!/main';
|
||||
$routeProvider.otherwise({redirectTo: '/main'});
|
||||
}
|
||||
}
|
||||
}])
|
||||
.config(function(toastrConfig) {
|
||||
angular.extend(toastrConfig, {
|
||||
autoDismiss: false,
|
||||
containerId: 'toast-container',
|
||||
maxOpened: 0,
|
||||
newestOnTop: true,
|
||||
positionClass: 'toast-bottom-right',
|
||||
preventDuplicates: false,
|
||||
preventOpenDuplicates: false,
|
||||
target: 'body'
|
||||
});
|
||||
})
|
||||
.factory('httpInterceptor', function httpInterceptor() {
|
||||
return {
|
||||
request: function(config) {
|
||||
return config;
|
||||
},
|
||||
|
||||
requestError: function(config) {
|
||||
return config;
|
||||
},
|
||||
|
||||
response: function(res) {
|
||||
return res;
|
||||
},
|
||||
|
||||
responseError: function(res) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
})
|
||||
.factory('api', function($http) {
|
||||
return {
|
||||
init: function() {
|
||||
var dblog_user = JSON.parse(localStorage.getItem('dblog_user'));
|
||||
if (dblog_user) {
|
||||
$http.defaults.headers.common['Authorization'] = dblog_user.token;
|
||||
$http.defaults.headers.post['Authorization'] = dblog_user.token;
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.run(function(api) {
|
||||
api.init();
|
||||
});
|
||||
19
webapp/bower.json
Normal file
19
webapp/bower.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "ipfs-ai-models-market",
|
||||
"description": "",
|
||||
"version": "0.0.0",
|
||||
"homepage": "",
|
||||
"license": "GNU",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"angular": "^1.6.2",
|
||||
"angular-route": "^1.6.1",
|
||||
"angular-messages": "^1.6.5",
|
||||
"angular-bootstrap-material": "abm#^0.1.4",
|
||||
"angular-bootstrap": "^2.5.0",
|
||||
"components-font-awesome": "^4.7.0",
|
||||
"angular-toastr": "^2.1.1",
|
||||
"cssMaterialColors": "*",
|
||||
"angular-chart.js": "^1.1.1"
|
||||
}
|
||||
}
|
||||
5
webapp/css/own.css
Normal file
5
webapp/css/own.css
Normal file
@@ -0,0 +1,5 @@
|
||||
.o_nav {
|
||||
background: #ffffff!important;
|
||||
color: #000000!important;
|
||||
/*border-bottom: 2px solid #4DD0E1!important;*/
|
||||
}
|
||||
BIN
webapp/img/icon.png
Normal file
BIN
webapp/img/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
73
webapp/index.html
Normal file
73
webapp/index.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="app" ng-cloak>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>ipfs-ai-models-market</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/icon.png">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Overpass+Mono:700|Raleway:700" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||
|
||||
|
||||
<link rel="stylesheet" href="bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
|
||||
<link rel="stylesheet" href="css/own.css">
|
||||
|
||||
<link href="bower_components/cssMaterialColors/colors.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body ng-app="webapp">
|
||||
<div ng-include="'views/navbar.html'"></div>
|
||||
<br><br><br><br>
|
||||
<div ng-view></div>
|
||||
|
||||
|
||||
|
||||
<!-- ELECTRON
|
||||
Insert this line above script imports
|
||||
Works for both browser and electron with the same code -->
|
||||
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
|
||||
|
||||
|
||||
<!-- Angular js -->
|
||||
<script src="bower_components/angular/angular.js"></script>
|
||||
<script src="bower_components/angular-route/angular-route.js"></script>
|
||||
<script src="bower_components/angular-messages/angular-messages.js"></script>
|
||||
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Angular Chart -->
|
||||
<script src="bower_components/chart.js/dist/Chart.min.js"></script>
|
||||
<script src="bower_components/angular-chart.js/dist/angular-chart.min.js"></script>
|
||||
|
||||
<!-- toastr -->
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/angular-toastr/dist/angular-toastr.css" />
|
||||
<script type="text/javascript" src="bower_components/angular-toastr/dist/angular-toastr.tpls.js"></script>
|
||||
|
||||
<!-- app's js -->
|
||||
<script src="app.js"></script>
|
||||
<script src="views/navbar.js"></script>
|
||||
<script src="views/signup/signup.js"></script>
|
||||
<script src="views/login/login.js"></script>
|
||||
<script src="views/main/main.js"></script>
|
||||
<script src="views/newmodel/newmodel.js"></script>
|
||||
<script src="views/profile/profile.js"></script>
|
||||
|
||||
|
||||
<!-- ELECTRON
|
||||
Insert this line after script imports -->
|
||||
<script>if (window.module) module = window.module;</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
13
webapp/package.json
Normal file
13
webapp/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "decentralized-blogging-platform",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"postinstall": "bower install",
|
||||
"prestart": "npm install",
|
||||
"start": "http-server"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": "^4.0.0"
|
||||
}
|
||||
}
|
||||
35
webapp/views/login/login.html
Executable file
35
webapp/views/login/login.html
Executable file
@@ -0,0 +1,35 @@
|
||||
<div class="container" style="margin-top: -60px;">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">
|
||||
Login
|
||||
</h4>
|
||||
<div class="form-group">
|
||||
<input ng-model="user.email" type="email" class="form-control" placeholder="Email">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input ng-model="user.password" type="password" class="form-control" placeholder="Password">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<a href="#!/signup" class="btn btn-raised btn-block c_o_pink300">Signup</a>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div ng-click="login()" class="btn btn-raised btn-block c_o_cyan300 pull-right">Login</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
36
webapp/views/login/login.js
Executable file
36
webapp/views/login/login.js
Executable file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.login', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/login', {
|
||||
templateUrl: 'views/login/login.html',
|
||||
controller: 'LoginCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('LoginCtrl', function($scope, $rootScope, $http, $routeParams, toastr) {
|
||||
$rootScope.server = ""
|
||||
$scope.user = {};
|
||||
|
||||
$scope.login = function() {
|
||||
$http({
|
||||
url: apiurl + 'login',
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": undefined
|
||||
},
|
||||
data: $scope.user
|
||||
})
|
||||
.then(function(data) {
|
||||
console.log("data: ");
|
||||
console.log(data.data);
|
||||
localStorage.setItem("dblog_user", JSON.stringify(data.data));
|
||||
window.location.reload();
|
||||
},
|
||||
function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
};
|
||||
});
|
||||
14
webapp/views/main/main.html
Executable file
14
webapp/views/main/main.html
Executable file
@@ -0,0 +1,14 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="card" style="width: 18rem;">
|
||||
<img class="card-img-top" ng-src="http://localhost:8080/ipfs/QmUE6hhNsyUA5emj2dviVDNYK7mSbPeZmRKeCYthmtemeA" alt="Card image cap">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Post1</h5>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
<a href="#" class="btn btn-primary">Go somewhere</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
16
webapp/views/main/main.js
Executable file
16
webapp/views/main/main.js
Executable file
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.main', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/main', {
|
||||
templateUrl: 'views/main/main.html',
|
||||
controller: 'MainCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('MainCtrl', function($scope, $rootScope, $http) {
|
||||
|
||||
|
||||
|
||||
});
|
||||
49
webapp/views/navbar.html
Executable file
49
webapp/views/navbar.html
Executable file
@@ -0,0 +1,49 @@
|
||||
<div ng-controller="NavbarCtrl">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">
|
||||
<i title="Server" class="fa fa-cube fa-1x"></i> decentralized-blogging-platform
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="#">Top Posts <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Top Writters</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0">
|
||||
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
<ul class="navbar-nav" ng-show="user">
|
||||
<li class="nav-item">
|
||||
<a href="#!/profile" class="nav-link">
|
||||
<i title="Profile" class="fa fa-user fa-1x"></i> {{user.username}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a ng-click="logout()" class="nav-link">
|
||||
<i title="Logout" class="fa fa-power-off fa-1x"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav" ng-show="!user">
|
||||
<li class="nav-item">
|
||||
<a href="#!/signup" class="nav-link">
|
||||
<i title="Signup" class="fa fa-sign-in fa-1x"></i> Signup
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#!/login" class="nav-link">
|
||||
<i title="Login" class="fa fa-sign-in fa-1x"></i> Login
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
20
webapp/views/navbar.js
Executable file
20
webapp/views/navbar.js
Executable file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.navbar', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/navbar', {
|
||||
templateUrl: 'views/navbar.html',
|
||||
controller: 'NavbarCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('NavbarCtrl', function($scope) {
|
||||
$scope.user = JSON.parse(localStorage.getItem("dblog_user"));
|
||||
console.log("user", $scope.user);
|
||||
$scope.logout = function() {
|
||||
localStorage.removeItem("dblog_user");
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
});
|
||||
51
webapp/views/navbarOLD.html
Normal file
51
webapp/views/navbarOLD.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<div ng-controller="NavbarCtrl">
|
||||
<nav class="navbar navbar-fixed-top o_nav">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#!/" title="darkID">
|
||||
<i title="Server" class="fa fa-cube fa-1x"></i> decentralized-blogging-platform
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse navbar-responsive-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="#!/stats" title="Stats">
|
||||
<i title="Server" class="fa fa-th-large fa-1x"></i> Models
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right" ng-show="user"><!--logged-->
|
||||
<li>
|
||||
<a href="#!/profile">
|
||||
<i title="Profile" class="fa fa-user fa-1x"></i> {{user.username}}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="" ng-click="logout()">
|
||||
<i title="Create Account" class="fa fa-sign-out fa-1x"></i> Logout
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right" ng-show="!user"><!--unlogged-->
|
||||
<li>
|
||||
<a href="#!/signup">
|
||||
<i title="Create Account" class="fa fa-sign-in fa-1x"></i> Signup
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right" ng-show="!user"><!--unlogged-->
|
||||
<li>
|
||||
<a href="#!/login">
|
||||
<i title="Login" class="fa fa-sign-in fa-1x"></i> Login
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
18
webapp/views/newmodel/newmodel.html
Normal file
18
webapp/views/newmodel/newmodel.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4>New model</h4>
|
||||
<input ng-model="model.title" placeholder="Title" type="text" class="form-control">
|
||||
<input ng-model="model.description" placeholder="Description" type="text" class="form-control">
|
||||
|
||||
<input type="file" file-model="file"/>
|
||||
|
||||
<input ng-model="model.accuracy" placeholder="Accuracy" type="text" class="form-control">
|
||||
<a ng-click="upload()" class="btn btn-raised pull-right c_o_pink300">Upload</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
79
webapp/views/newmodel/newmodel.js
Normal file
79
webapp/views/newmodel/newmodel.js
Normal file
@@ -0,0 +1,79 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.newmodel', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/newmodel', {
|
||||
templateUrl: 'views/newmodel/newmodel.html',
|
||||
controller: 'NewModelCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('NewModelCtrl', function($scope, $rootScope, $http, toastr) {
|
||||
|
||||
$scope.file = {};
|
||||
|
||||
$scope.upload = function() {
|
||||
console.log("upload model");
|
||||
var formdata = new FormData();
|
||||
formdata.append("file", $scope.file);
|
||||
|
||||
//add the file to ipfs
|
||||
/*$http({
|
||||
url: ipfs_url + 'add',
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": undefined
|
||||
},
|
||||
data: formdata
|
||||
})
|
||||
.then(function(data) {
|
||||
console.log("data: ");
|
||||
console.log(data.data);
|
||||
toastr.success("Model added to IPFS");
|
||||
},
|
||||
function(data) {
|
||||
console.log(data);
|
||||
toastr.error("Error adding Model to IPFS");
|
||||
});*/
|
||||
|
||||
//add the data to userdata
|
||||
$http({
|
||||
url: clienturl + 'model',
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": undefined
|
||||
},
|
||||
data: $scope.model
|
||||
})
|
||||
.then(function(data) {
|
||||
console.log("data: ");
|
||||
console.log(data.data);
|
||||
window.location="/";
|
||||
toastr.success("Model uploaded");
|
||||
},
|
||||
function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
})
|
||||
.directive('fileModel', ['$parse', function($parse) {
|
||||
//directive code from https://www.tutorialspoint.com/angularjs/angularjs_upload_file.htm
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
var model = $parse(attrs.fileModel);
|
||||
var modelSetter = model.assign;
|
||||
element.bind('change', function() {
|
||||
scope.$apply(function() {
|
||||
modelSetter(scope, element[0].files[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
31
webapp/views/profile/profile.html
Normal file
31
webapp/views/profile/profile.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div ng-include="'views/user_template.html'"></div>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="card">
|
||||
<table class="table table-striped table-hover ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th>Accuracy</th>
|
||||
<th>Rating</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="model in user.models">
|
||||
<td>1</td>
|
||||
<td>{{model.title}}</td>
|
||||
<td>{{model.description}}</td>
|
||||
<td>{{model.accuracy}}</td>
|
||||
<td>{{model.rating}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
24
webapp/views/profile/profile.js
Normal file
24
webapp/views/profile/profile.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.profile', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/profile', {
|
||||
templateUrl: 'views/profile/profile.html',
|
||||
controller: 'ProfileCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('ProfileCtrl', function($scope, $rootScope, $http) {
|
||||
|
||||
$http.get(clienturl + 'user')
|
||||
.then(function(data) {
|
||||
console.log('data success');
|
||||
console.log(data);
|
||||
$scope.user = data.data;
|
||||
localStorage.setItem("ai_user", JSON.stringify($scope.user));
|
||||
|
||||
}, function(data) {
|
||||
console.log('no user');
|
||||
});
|
||||
});
|
||||
38
webapp/views/signup/signup.html
Executable file
38
webapp/views/signup/signup.html
Executable file
@@ -0,0 +1,38 @@
|
||||
<div class="container" style="margin-top: -80px;">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">
|
||||
Signup
|
||||
</h4>
|
||||
<div class="form-group">
|
||||
<input ng-model="user.username" class="form-control" placeholder="Username">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input ng-model="user.email" type="email" class="form-control" placeholder="Email">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input ng-model="user.password" type="password" class="form-control" placeholder="Password">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<a href="#!/login" class="btn btn-raised btn-block c_o_blue300">Cancel</a>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div ng-click="signup()" class="btn btn-raised btn-block c_o_green300 pull-right">Signup</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
34
webapp/views/signup/signup.js
Executable file
34
webapp/views/signup/signup.js
Executable file
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.signup', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/signup', {
|
||||
templateUrl: 'views/signup/signup.html',
|
||||
controller: 'SignupCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('SignupCtrl', function($scope, $http, $routeParams, $rootScope) {
|
||||
$scope.signup = function() {
|
||||
console.log('Doing signup', $scope.user);
|
||||
$http({
|
||||
url: apiurl + 'signup',
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": undefined
|
||||
},
|
||||
data: $scope.user
|
||||
})
|
||||
.then(function(data) {
|
||||
console.log("data: ");
|
||||
console.log(data.data);
|
||||
window.location="/#!/login";
|
||||
|
||||
},
|
||||
function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user