OSDN Git Service

simple login
authorhimetani_cafe <fumifumi@yasunaga-lab.bio.kyutech.ac.jp>
Sat, 25 Jul 2015 09:10:47 +0000 (18:10 +0900)
committerhimetani_cafe <fumifumi@yasunaga-lab.bio.kyutech.ac.jp>
Sat, 25 Jul 2015 09:10:47 +0000 (18:10 +0900)
17 files changed:
.gitignore
auth [new file with mode: 0644]
client/app/app.js
client/app/components/board/board.controller.js
client/app/components/board/board.js
client/app/components/login/login.controller.js
client/app/components/login/login.css
client/app/components/login/login.html
client/app/components/login/login.js
client/app/shared/navbar/navbar.controller.js
client/app/shared/navbar/navbar.html
client/assets/vendor/angular/angular-route.min.js [new file with mode: 0644]
client/index.html
orm.js [new file with mode: 0644]
package.json
server/auth/login/index.js
server/express.js

index a51b236..5b23dca 100644 (file)
@@ -4,4 +4,5 @@ util/json/
 notes/
 node_modules/
 .DS_Store
+db/
 .EosLog
diff --git a/auth b/auth
new file mode 100644 (file)
index 0000000..e69de29
index ac1c26b..c2e3b55 100644 (file)
@@ -1,11 +1,24 @@
 'use strict';
 
-angular.module('zephyrApp', ['ui.bootstrap', 'ui.router', 'restangular'])
-.config(function($locationProvider, $stateProvider, $urlRouterProvider,  $httpProvider) {
+angular.module('zephyrApp', ['ui.bootstrap', 'ui.router', 'restangular','ngRoute'])
+.config(function($locationProvider, $stateProvider, $urlRouterProvider,  $httpProvider){
     $locationProvider.html5Mode({
         enabled: true,
         requireBase: false
     })
-    $urlRouterProvider.otherwise('/')
+    $urlRouterProvider.otherwise('/login')
     $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
+
+    $httpProvider.interceptors.push(function($q, $location) { 
+        return { 
+            response: function(response) { // do something on success 
+                return response 
+            }, 
+            responseError: function(response) { 
+                if (response.status === 401) $location.url('/login') 
+                    return $q.reject(response); 
+            } 
+        }; 
+    })
+
 })
index 8d5d336..0bfdf78 100644 (file)
@@ -37,7 +37,7 @@ angular.module('zephyrApp')
     })
 
     var note = $state.params.id
-    if(note !== 'new') {
+    if(note !== '') {
         $scope.noteName = note
         var baseNoteInfo = Restangular.all('/api/noteInfo/'+note)
         baseNoteInfo.getList().then(function(commands) {
index 94e9a62..9393d83 100644 (file)
@@ -3,7 +3,7 @@
 angular.module('zephyrApp')
 .config(function($stateProvider) {
     $stateProvider
-    .state('note', {
+    .state('board', {
         url:'/board/:id?',
         templateUrl:'/client/app/components/board/board.html',
         controller: 'BoardController'
index 35dc03b..7fb6618 100644 (file)
@@ -2,6 +2,18 @@
 
 angular.module('zephyrApp')
 .controller('LoginController', function ($scope, $modal, Restangular, $state) {
+    var baseLogin = Restangular.all('/auth/login')
 
+    $scope.submit = function() {
+        var params = {
+            username: $scope.username,
+            password: $scope.password
+        }
 
+        console.log(params)
+
+        baseLogin.post(JSON.stringify(params)).then(function(status) {
+            $state.go('note')
+        })
+    }
 });
index f2d18db..ae320b2 100644 (file)
@@ -1,9 +1,3 @@
-body {
-    /*padding-top: 40px;*/
-    /*padding-bottom: 40px;*/
-    background-color: #eee;
-}
-
 .form-signin {
     max-width: 330px;
     padding: 15px;
index b845690..705452c 100644 (file)
@@ -1,11 +1,11 @@
 <div class="container">
 
-<form class="form-signin" method="post" action="/auth/login" ng-model="auth" >
-    <h2 class="form-signin-heading">Login</h2>
-    <label for="inputEmail" class="sr-only">Email address</label>
-    <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
-    <label for="inputPassword" class="sr-only">Password</label>
-    <input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
+<form class="form-signin" method="post" ng-submit="submit()" >
+    <h2 class="text-center" class="form-signin-heading">Login</h2>
+    <label class="sr-only">Username</label>
+    <input type="text" name="username" class="form-control" ng-model="username" placeholder="Username" required autofocus>
+    <label class="sr-only">Password</label>
+    <input type="password" name="password" class="form-control" ng-model="password" placeholder="Password" required>
     <div class="checkbox">
         <label>
             <input type="checkbox" value="remember-me"> Remember me
index fb53443..fcdaca7 100644 (file)
@@ -1,19 +1,12 @@
 'use strict';
 
 angular.module('zephyrApp')
-.config(function($stateProvider) {
+.config(function($stateProvider, $httpProvider) {
     $stateProvider
     .state('login', {
-        url:'/',
+        url:'/login',
         templateUrl:'/client/app/components/login/login.html',
         controller: 'LoginController',
         css: '/client/app/components/login/login.css'
     })
-    /*
-    .state('note', {
-        url: '/board/:note'
-        //templateUrl:'/client/app/components/board/board.html',
-        //controller: 'BoardController'
-    })
-    */
-});
+    });
index e4a41db..d2066e4 100644 (file)
@@ -1,16 +1,13 @@
 'use strict';
 
 angular.module('zephyrApp')
-.controller('NavbarController', function($scope) {
-    $scope.isBoard         = true 
-        $scope.isWorkspace = false 
-        $scope.isNotes     = false 
-
-    $scope.activate = function(name) { 
+.controller('NavbarController', function($scope, $state) {
+    function activate(name) { 
         $scope.isBoard = name === 'board'
         $scope.isWorkspace = name === 'workspace'
         $scope.isNotes = name === 'notes'
     }
-});
+    activate($state.current.name)
+})
 
 
index 1c07809..5625703 100644 (file)
@@ -4,9 +4,9 @@
     </div>
     <div class="navbar-collapse collapse navbar-responsive-collapse">
         <ul class="nav navbar-nav">
-            <li ng-class="{active: isBoard}"><a href="/board/new" ng-click="activate('board')">Board</a></li>
-            <li ng-class="{active: isWorkspace}"><a href="/workspace" ng-click="activate('workspace')">Workspace</a></li>
-            <li ng-class="{active: isNotes}"><a href="/notes" ng-click="activate('notes')">Notes</a></li>
+            <li ng-class="{active: isBoard}"><a href="/board/">Board</a></li>
+            <li ng-class="{active: isWorkspace}"><a href="/workspace">Workspace</a></li>
+            <li ng-class="{active: isNotes}"><a href="/notes">Notes</a></li>
         </ul>
     </div>
 </nav>
diff --git a/client/assets/vendor/angular/angular-route.min.js b/client/assets/vendor/angular/angular-route.min.js
new file mode 100644 (file)
index 0000000..ca3e81b
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ AngularJS v1.3.15
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(q,d,C){'use strict';function v(r,k,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,f,b,c,y){function z(){l&&(h.cancel(l),l=null);m&&(m.$destroy(),m=null);n&&(l=h.leave(n),l.then(function(){l=null}),n=null)}function x(){var b=r.current&&r.current.locals;if(d.isDefined(b&&b.$template)){var b=a.$new(),c=r.current;n=y(b,function(b){h.enter(b,null,n||f).then(function(){!d.isDefined(t)||t&&!a.$eval(t)||k()});z()});m=c.scope=b;m.$emit("$viewContentLoaded");
+m.$eval(w)}else z()}var m,n,l,t=b.autoscroll,w=b.onload||"";a.$on("$routeChangeSuccess",x);x()}}}function A(d,k,h){return{restrict:"ECA",priority:-400,link:function(a,f){var b=h.current,c=b.locals;f.html(c.$template);var y=d(f.contents());b.controller&&(c.$scope=a,c=k(b.controller,c),b.controllerAs&&(a[b.controllerAs]=c),f.data("$ngControllerController",c),f.children().data("$ngControllerController",c));y(a)}}}q=d.module("ngRoute",["ng"]).provider("$route",function(){function r(a,f){return d.extend(Object.create(a),
+f)}function k(a,d){var b=d.caseInsensitiveMatch,c={originalPath:a,regexp:a},h=c.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,d,b,c){a="?"===c?c:null;c="*"===c?c:null;h.push({name:b,optional:!!a});d=d||"";return""+(a?"":d)+"(?:"+(a?d:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");c.regexp=new RegExp("^"+a+"$",b?"i":"");return c}var h={};this.when=function(a,f){var b=d.copy(f);d.isUndefined(b.reloadOnSearch)&&(b.reloadOnSearch=!0);
+d.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);h[a]=d.extend(b,a&&k(a,b));if(a){var c="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";h[c]=d.extend({redirectTo:a},k(c,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,f,b,c,k,q,x){function m(b){var e=s.current;
+(v=(p=l())&&e&&p.$$route===e.$$route&&d.equals(p.pathParams,e.pathParams)&&!p.reloadOnSearch&&!w)||!e&&!p||a.$broadcast("$routeChangeStart",p,e).defaultPrevented&&b&&b.preventDefault()}function n(){var u=s.current,e=p;if(v)u.params=e.params,d.copy(u.params,b),a.$broadcast("$routeUpdate",u);else if(e||u)w=!1,(s.current=e)&&e.redirectTo&&(d.isString(e.redirectTo)?f.path(t(e.redirectTo,e.params)).search(e.params).replace():f.url(e.redirectTo(e.pathParams,f.path(),f.search())).replace()),c.when(e).then(function(){if(e){var a=
+d.extend({},e.resolve),b,g;d.forEach(a,function(b,e){a[e]=d.isString(b)?k.get(b):k.invoke(b,null,null,e)});d.isDefined(b=e.template)?d.isFunction(b)&&(b=b(e.params)):d.isDefined(g=e.templateUrl)&&(d.isFunction(g)&&(g=g(e.params)),g=x.getTrustedResourceUrl(g),d.isDefined(g)&&(e.loadedTemplateUrl=g,b=q(g)));d.isDefined(b)&&(a.$template=b);return c.all(a)}}).then(function(c){e==s.current&&(e&&(e.locals=c,d.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,u))},function(b){e==s.current&&a.$broadcast("$routeChangeError",
+e,u,b)})}function l(){var a,b;d.forEach(h,function(c,h){var g;if(g=!b){var k=f.path();g=c.keys;var m={};if(c.regexp)if(k=c.regexp.exec(k)){for(var l=1,n=k.length;l<n;++l){var p=g[l-1],q=k[l];p&&q&&(m[p.name]=q)}g=m}else g=null;else g=null;g=a=g}g&&(b=r(c,{params:d.extend({},f.search(),a),pathParams:a}),b.$$route=c)});return b||h[null]&&r(h[null],{params:{},pathParams:{}})}function t(a,b){var c=[];d.forEach((a||"").split(":"),function(a,d){if(0===d)c.push(a);else{var f=a.match(/(\w+)(?:[?*])?(.*)/),
+h=f[1];c.push(b[h]);c.push(f[2]||"");delete b[h]}});return c.join("")}var w=!1,p,v,s={routes:h,reload:function(){w=!0;a.$evalAsync(function(){m();n()})},updateParams:function(a){if(this.current&&this.current.$$route)a=d.extend({},this.current.params,a),f.path(t(this.current.$$route.originalPath,a)),f.search(a);else throw B("norout");}};a.$on("$locationChangeStart",m);a.$on("$locationChangeSuccess",n);return s}]});var B=d.$$minErr("ngRoute");q.provider("$routeParams",function(){this.$get=function(){return{}}});
+q.directive("ngView",v);q.directive("ngView",A);v.$inject=["$route","$anchorScroll","$animate"];A.$inject=["$compile","$controller","$route"]})(window,window.angular);
+//# sourceMappingURL=angular-route.min.js.map
index f820e8d..4d7417c 100644 (file)
@@ -18,6 +18,7 @@
         <!-- endinject -->
         <!-- angular:js -->
         <script src="/client/assets/vendor/angular/angular.min.js"></script>
+        <script src="/client/assets/vendor/angular/angular-route.min.js"></script>
         <script src="/client/assets/vendor/angular/angular-resource.min.js"></script>
         <!-- endinject -->
         <!-- vendor:js -->
diff --git a/orm.js b/orm.js
new file mode 100644 (file)
index 0000000..c41cb77
--- /dev/null
+++ b/orm.js
@@ -0,0 +1,35 @@
+var Sequelize = require('sequelize')
+
+var sequelize = new Sequelize('database', 'username', 'password', {
+    host: 'localhost',
+    dialect: 'sqlite',
+
+    pool: {
+        max: 5,
+        min: 0,
+        idle: 10000
+    },
+
+    // SQLite only
+    storage: 'db/auth.db'
+});
+
+var User = sequelize.define('user', {
+      firstName: {
+              type: Sequelize.STRING,
+                  field: 'first_name' // Will result in an attribute that is firstName when user facing but first_name in the database
+                    },
+                      lastName: {
+                              type: Sequelize.STRING
+                                }
+}, {
+      freezeTableName: true // Model tableName will be the same as the model name
+});
+
+User.sync({force: true}).then(function () {
+      // Table created
+        return User.create({
+                firstName: 'John',
+                    lastName: 'Hancock'
+                      });
+});
index 7ac37f2..a304d93 100644 (file)
@@ -6,10 +6,15 @@
   "dependencies": {
     "bluebird": "^2.9.24",
     "body-parser": "^1.12.3",
+    "connect-flash": "^0.1.1",
+    "cookie-parser": "^1.3.5",
     "ejs": "^2.3.1",
     "express": "^4.12.3",
+    "express-session": "^1.11.3",
     "lodash": "^3.8.0",
     "passport": "^0.2.2",
+    "passport-local": "^1.0.0",
+    "sequelize": "^3.4.1",
     "sqlite3": "^3.0.9",
     "thunkify": "^2.1.2"
   },
index 901ebbf..9f2bf41 100644 (file)
@@ -1,12 +1,62 @@
 'use strict'
 
-var express = require('express'),
-    router  = express.Router(),
-    path    = require('path')
+var express        = require('express'),
+    router         = express.Router(),
+    path           = require('path'),
+    passport       = require('passport'),
+    LocalStrategy = require('passport-local').Strategy
 
-router.post('/', function(req, res) {
-    console.log(req)
-    res.sendStatus(401)
+var users = [
+    { id: 1, username: 'bob', password: 'secret', email: 'bob@example.com' }
+    , { id: 2, username: 'joe', password: 'birthday', email: 'joe@example.com' }
+];
+
+function findById(id, fn) {
+    var idx = id - 1;
+    if (users[idx]) {
+        fn(null, users[idx]);
+    } else {
+        fn(new Error('User ' + id + ' does not exist'));
+    }
+}
+
+function findByUsername(username, fn) {
+    for (var i = 0, len = users.length; i < len; i++) {
+        var user = users[i];
+        if (user.username === username) {
+            return fn(null, user);
+        }
+    }
+    return fn(null, null);
+}
+
+passport.serializeUser(function(user, done) {
+    done(null, user.id)
+})
+
+passport.deserializeUser(function(id, done) {
+    findById(id, function(err, user) {
+        done(null, user.id)
+    })
 })
 
+passport.use(new LocalStrategy(
+    function(username, password, done) {
+        process.nextTick(function() {
+            findByUsername(username, function(err, user) {
+                if(err){ return done(err) }
+                if(!user) { return done(null, false, { message: 'Unknown user ' + username })}
+                if(user.password != password) { return done(null, false, { message: 'Invalid password' }) }
+                return done(null, user)
+            })
+        })
+    }
+))
+
+
+router.post('/', passport.authenticate('local'),
+    function(req, res) {
+        res.send('hoge');
+    })
+
 module.exports = router
index 7bc47c3..f687bf9 100644 (file)
@@ -3,7 +3,11 @@
 var express    = require('express'),
     path       = require('path'),
     config     = require('./config'),
-    bodyParser = require('body-parser')
+    bodyParser = require('body-parser'),
+    flash      = require('connect-flash'),
+    session    = require('express-session'),
+    cookieParser = require('cookie-parser'),
+    passport   = require('passport')
 
 module.exports = function(app) {
     app.set('views', config.root+ '/server/views')
@@ -11,6 +15,15 @@ module.exports = function(app) {
     app.set('view engine', 'html')
     app.use('/workspace', express.static('./workspace/'))
     app.use(bodyParser.json())
+    app.use(cookieParser())
+    app.use(session({ 
+        secret: '123',
+        resave: true,
+        saveUninitialized: true
+    }))
+    app.use(flash())
+    app.use(passport.initialize())
+    app.use(passport.session())
 
     if(app.get('env') === 'development') {
         app.use('/client/', express.static('./client/'))