Angular HTML5 Mode & OAuth token authentication

James Peret 10 gadi atpakaļ
vecāks
revīzija
ee5e6aee31

+ 5 - 0
Gruntfile.js

@@ -25,6 +25,10 @@ module.exports = function (grunt) {
25 25
     dist: 'dist'
26 26
   };
27 27
 
28
+  var modRewrite = require('connect-modrewrite');
29
+
30
+  grunt.loadNpmTasks('grunt-contrib-connect');
31
+
28 32
   // Define the configuration for all the tasks
29 33
   grunt.initConfig({
30 34
 
@@ -80,6 +84,7 @@ module.exports = function (grunt) {
80 84
           open: true,
81 85
           middleware: function (connect) {
82 86
             return [
87
+              modRewrite(['^[^\\.]*$ /index.html [L]']),
83 88
               connect.static('.tmp'),
84 89
               connect().use(
85 90
                 '/bower_components',

+ 3 - 0
app/index.html

@@ -1,6 +1,7 @@
1 1
 <!doctype html>
2 2
 <html>
3 3
   <head>
4
+    <base href="/" target="_blank">
4 5
     <meta charset="utf-8">
5 6
     <title></title>
6 7
     <meta name="description" content="">
@@ -64,10 +65,12 @@
64 65
 
65 66
         <!-- build:js({.tmp,app}) scripts/scripts.js -->
66 67
         <script src="scripts/app.js"></script>
68
+        <script src="scripts/controllers/getting-started-ctrl.js"></script>
67 69
         <script src="scripts/controllers/rulebook-ctrl.js"></script>
68 70
         <script src="scripts/controllers/rest-api-v1-ctrl.js"></script>
69 71
         <script src="scripts/controllers/get-missions-ctrl.js"></script>
70 72
         <script src="scripts/controllers/about.js"></script>
73
+        <script src="scripts/services/oauth-service.js"></script>
71 74
         <script src="scripts/services/get-data.js"></script>
72 75
         <!-- endbuild -->
73 76
 </body>

+ 8 - 2
app/scripts/app.js

@@ -13,6 +13,7 @@ angular
13 13
     'ngAnimate',
14 14
     'ngCookies',
15 15
     'ngResource',
16
+    'ngRoute',
16 17
     'ui.router',
17 18
     'ngSanitize',
18 19
     'ngTouch',
@@ -21,8 +22,13 @@ angular
21 22
     'jsonFormatter',
22 23
     'angularSpinner'
23 24
   ])
24
-  .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', function($stateProvider, $urlRouterProvider, $httpProvider) {
25
+  .config(['$locationProvider', '$stateProvider', '$urlRouterProvider', '$httpProvider', function($locationProvider, $stateProvider, $urlRouterProvider, $httpProvider) {
25 26
     // Configs
27
+    $locationProvider.html5Mode({
28
+      enabled: true,
29
+      requireBase: true,
30
+      rewriteLinks: true
31
+    });
26 32
     //Enable cross domain calls
27 33
     $httpProvider.defaults.useXDomain = true;
28 34
     //Remove the header used to identify ajax call  that would prevent CORS from working
@@ -32,7 +38,7 @@ angular
32 38
     .state('getting-started', {
33 39
       url: "/",
34 40
       templateUrl: 'views/getting-started.html',
35
-      controller: 'AboutCtrl'
41
+      controller: 'GettingStartedCtrl'
36 42
     })
37 43
     .state('rulebook', {
38 44
       url: "/rulebook",

+ 23 - 2
app/scripts/controllers/get-missions-ctrl.js

@@ -8,15 +8,23 @@
8 8
  * Controller of the avalancheDocsApp
9 9
  */
10 10
 angular.module('avalancheDocsApp')
11
-  .controller('GetMissionsController',['$scope', '$rootScope', 'GetData', 'usSpinnerService', function ($scope, $rootScope, GetData, usSpinnerService) {
11
+  .controller('GetMissionsController',['$scope', '$rootScope', 'GetData', 'usSpinnerService', 'OAuthService', function ($scope, $rootScope, GetData, usSpinnerService, OAuthService) {
12 12
 
13 13
     $scope.response = {};
14 14
     $scope.hideResult = true;
15
+    $scope.token = [];
16
+    $scope.token[0] = 'none';
17
+    $scope.selectedToken = $scope.token[0];
18
+    if(OAuthService.getToken() != ""){
19
+      $scope.token[1] = OAuthService.getToken();
20
+      $scope.selectedToken = $scope.token[1];
21
+    }
22
+
15 23
     GetData.get()
16 24
 
17 25
     $scope.call_api = function(url){
18 26
       usSpinnerService.spin('spinner-1');
19
-      GetData.fetch(url);
27
+      GetData.fetch(url, $scope.selectedToken);
20 28
     }
21 29
     $scope.hideResponse = function() {
22 30
       $scope.hideResult = true;
@@ -34,8 +42,21 @@ angular.module('avalancheDocsApp')
34 42
       usSpinnerService.stop('spinner-1');
35 43
     });
36 44
 
45
+    $rootScope.$on('auth:success', function() {
46
+      if(!$scope.$$phase) {
47
+        $scope.$apply(function(){
48
+          $scope.token[1] = OAuthService.getToken();
49
+          $scope.selectedToken = $scope.token[1];
50
+        });
51
+      } else {
52
+          $scope.token[1] = OAuthService.getToken();
53
+          $scope.selectedToken = $scope.token[1];
54
+      }
55
+    });
56
+
37 57
     $scope.status = function(code) {
38 58
       if(code == 200){ return "200 OK"}
59
+      if(code == 401){ return "401 Unauthorized"}
39 60
     }
40 61
     $scope.stringfy = function(data) {
41 62
       return JSON.stringify(data, null, 4);

+ 24 - 0
app/scripts/controllers/getting-started-ctrl.js

@@ -0,0 +1,24 @@
1
+'use strict';
2
+
3
+/**
4
+ * @ngdoc function
5
+ * @name avalancheDocsApp.controller:AboutCtrl
6
+ * @description
7
+ * # AboutCtrl
8
+ * Controller of the avalancheDocsApp
9
+ */
10
+angular.module('avalancheDocsApp')
11
+  .controller('GettingStartedCtrl', ['$scope', '$cookies', '$sanitize', 'OAuthService', '$location', function ($scope, $cookies, $sanitize, OAuthService, $location) {
12
+
13
+    OAuthService.lookForAuthCode();
14
+
15
+    var before_login_page = $cookies.get('avalanche_docs_before_login_page');
16
+    if(before_login_page != undefined) {
17
+      console.log("redirecting to: " + $sanitize(before_login_page));
18
+      $cookies.remove('avalanche_docs_before_login_page')
19
+      $location.path($sanitize(before_login_page)).replace();
20
+    }
21
+
22
+
23
+
24
+  }]);

+ 15 - 1
app/scripts/controllers/rest-api-v1-ctrl.js

@@ -8,8 +8,22 @@
8 8
  * Controller of the avalancheDocsApp
9 9
  */
10 10
 angular.module('avalancheDocsApp')
11
-  .controller('RestAPIv1Ctrl', ['$scope', '$location', function ($scope, $location) {
11
+  .controller('RestAPIv1Ctrl', ['$scope', '$location', '$cookies', '$window',  function ($scope, $location, $cookies, $window) {
12
+
12 13
     $scope.isActive = function (viewLocation) {
13 14
         return viewLocation === $location.path();
14 15
     };
16
+
17
+    $scope.token = $cookies.get('avalanche-docs-token');
18
+    if($scope.token == undefined) {
19
+      $scope.token = "none";
20
+      $scope.hideToken = true;
21
+    }
22
+
23
+    $scope.authorizeUser = function(){
24
+      console.log($location.url());
25
+      $cookies.put('avalanche_docs_before_login_page', $location.url());
26
+      $window.location.href = 'http://localhost:5000/oauth/authorize?client_id=d514f58c234d69ce1405f00dbef842bd785c09201b35a746d87306f5e69fd02b&redirect_uri=http://localhost:9000/&response_type=code';
27
+    }
28
+
15 29
   }]);

+ 17 - 8
app/scripts/services/get-data.js

@@ -1,18 +1,27 @@
1 1
 angular.module('avalancheDocsApp')
2 2
 .service('GetData', [ '$rootScope', '$http',  function($rootScope, $http) {
3 3
   var response = {};
4
-  this.fetch = function(url){
4
+  this.fetch = function(url, token){
5 5
     console.log("Requesting data from " + url)
6 6
     $http({
7 7
       method: 'GET',
8
-      url: 'http://localhost:5000/api' + url
9
-    }).success(function(data, status, headers, config) {
8
+      url: 'http://localhost:5000/api' + url,
9
+      headers: { 'Authorization' : "Bearer " + token }
10
+    }).then(function(data, status, headers, config) {
10 11
       console.log("API Request SUCCESSFULL")
11
-
12
-      response.data = data;
13
-      response.status = status;
14
-      response.headers = headers;
15
-      response.config = config;
12
+      response.data = data.data;
13
+      response.status = data.status;
14
+      response.headers = data.headers;
15
+      response.config = data.config;
16
+      console.log(response)
17
+      $rootScope.$broadcast('get-data:finished');
18
+    },
19
+    function(data, status) {
20
+      console.log("API Request FAILED")
21
+      response.data = data.data;
22
+      response.status = data.status;
23
+      response.headers = data.headers;
24
+      response.config = data.config;
16 25
       console.log(response)
17 26
       $rootScope.$broadcast('get-data:finished');
18 27
     });

+ 38 - 0
app/scripts/services/oauth-service.js

@@ -0,0 +1,38 @@
1
+angular.module('avalancheDocsApp')
2
+.service('OAuthService', [ '$rootScope', '$http', '$location', '$routeParams', '$cookies',  function($rootScope, $http, $location, $routeParams, $cookies) {
3
+  var code = {};
4
+  var token = $cookies.get('avalanche_docs_token');;
5
+  this.lookForAuthCode = function(){
6
+    code = $location.search().code;
7
+    if(code != undefined) {
8
+      console.log(code);
9
+      // Reset URL
10
+      $location.search("code", null);
11
+      $routeParams= null;
12
+      this.authorize(code);
13
+    }
14
+  }
15
+
16
+  this.authorize = function(code){
17
+    $http({
18
+      method: 'POST',
19
+      url: 'http://localhost:5000/oauth/token?client_id=d514f58c234d69ce1405f00dbef842bd785c09201b35a746d87306f5e69fd02b&client_secret=de63eb190485179d713df3e15339eb618e78e94ab96185621112dd0e5215997c&grant_type=authorization_code&redirect_uri=http://localhost:9000/&code=' + code
20
+    }).then(function(data) {
21
+      token = data.data.access_token;
22
+      console.log("Token Authentication SUCCESSFULL")
23
+      console.log(token);
24
+      $cookies.put('avalanche_docs_token', token);
25
+      $rootScope.$broadcast('auth:success');
26
+    },
27
+    function(data) {
28
+      console.log("Token Authentication FAILED")
29
+      console.log(data);
30
+      $rootScope.$broadcast('auth:failed');
31
+    });
32
+  }
33
+
34
+  this.getToken = function() {
35
+    return token;
36
+  }
37
+
38
+}])

+ 18 - 2
app/views/get-missions.html

@@ -39,12 +39,28 @@
39 39
   <tabset class="top-spacer">
40 40
     <tab heading="Try It">
41 41
       <form class="top-spacer">
42
+        <fieldset class="form-group">
43
+          <div class="row">
44
+            <div class="col-sm-8">
45
+              <label for="api-token-select">OAuth Access Token</label>
46
+              <select class="form-control " id="api-token-select" ng-options="option for option in token track by token" ng-model="selectedToken" style="height: 38px;">
47
+                <option ng-repeat="option in token" value="{{option}}">{{option}}</option>
48
+              </select>
49
+            </div>
50
+            <div class="col-sm-4">
51
+              <br>
52
+              <a ng-click="authorizeUser()" class="btn btn-secondary-outline btn-sm" role="button" style="margin-top:10px;">Get Token</a>
53
+            </div>
54
+          </div>
55
+        </fieldset>
42 56
         <div class="row">
43 57
           <div class="col-sm-8">
44 58
             <input type="text" class="form-control" id="exampleInputAmount" placeholder="http://avalanche.network/api/missions" disabled>
45 59
           </div>
46
-          <button type="submit" class="btn btn-success" ng-click="call_api('/missions')">Try It</button>
47
-          <button type="submit" class="btn" ng-click="hideResponse()" ng-hide="hideResult">Hide</button>
60
+          <div class="col-sm-4">
61
+            <button type="submit" class="btn btn-success" ng-click="call_api('/missions')">Try It</button>
62
+            <button type="submit" class="btn" ng-click="hideResponse()" ng-hide="hideResult">Hide</button>
63
+          </div>
48 64
         </div>
49 65
       </form>
50 66
       <div class="table-responsive col-sm-12" ng-hide="hideResult">

+ 2 - 1
package.json

@@ -2,6 +2,7 @@
2 2
   "name": "avalanchedocs",
3 3
   "private": true,
4 4
   "devDependencies": {
5
+    "connect-modrewrite": "^0.8.2",
5 6
     "grunt": "^0.4.5",
6 7
     "grunt-angular-templates": "^0.5.7",
7 8
     "grunt-autoprefixer": "^2.0.0",
@@ -37,4 +38,4 @@
37 38
   "scripts": {
38 39
     "test": "grunt test"
39 40
   }
40
-}
41
+}