1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 10:19:30 +02:00

Create seperate database table for AccessTokens to hide jwt token and tokenId from user

This commit is contained in:
Vishal Banthia 2015-11-26 02:36:09 +09:00
parent 62413b3780
commit 9cb231391a
11 changed files with 97 additions and 71 deletions

View file

@ -309,20 +309,23 @@ dbapi.loadDevice = function(serial) {
} }
dbapi.saveUserAccessToken = function(email, token) { dbapi.saveUserAccessToken = function(email, token) {
return db.run(r.table('users').get(email).update({ return db.run(r.table('accessTokens').insert({
accessTokens: r.row('accessTokens').default([]).append({ email: email
title: token.title , id: token.id
, tokenId: token.tokenId , title: token.title
, jwt: token.jwt , jwt: token.jwt
})
})) }))
} }
dbapi.removeUserAccessToken = function(email, title) { dbapi.removeUserAccessToken = function(email, title) {
return db.run(r.table('users').get(email).update({ return db.run(r.table('accessTokens').getAll(email, {
accessTokens: r.row('accessTokens').default([]).filter(function(token) { index: 'email'
return token('title').ne(title) }).filter({"title": title}).delete())
}) }
dbapi.loadAccessTokens = function(email) {
return db.run(r.table('accessTokens').getAll(email, {
index: 'email'
})) }))
} }

View file

@ -8,17 +8,18 @@ module.exports = {
indexFunction: function(user) { indexFunction: function(user) {
return user('adbKeys')('fingerprint') return user('adbKeys')('fingerprint')
} }
, accessTokens: {
indexFunction: function(user) {
return user('accessTokens')('tokenId')
}
}
, options: { , options: {
multi: true multi: true
} }
} }
} }
} }
, accessTokens: {
primaryKey: 'id'
, indexes: {
email: null
}
}
, vncauth: { , vncauth: {
primaryKey: 'password' primaryKey: 'password'
, indexes: { , indexes: {

View file

@ -200,6 +200,29 @@ module.exports = function(options) {
}) })
}) })
app.get('/app/api/v1/accessTokens', function(req, res) {
dbapi.loadAccessTokens(req.user.email)
.then(function(cursor) {
return Promise.promisify(cursor.toArray, cursor)()
.then(function(list) {
var titles = []
list.forEach(function(token) {
titles.push(token.title)
})
res.json({
success: true
, titles: titles
})
})
})
.catch(function(err) {
log.error('Failed to load tokens: ', err.stack)
res.json(500, {
success: false
})
})
})
server.listen(options.port) server.listen(options.port)
log.info('Listening on port %d', options.port) log.info('Listening on port %d', options.port)
} }

View file

@ -352,14 +352,13 @@ module.exports = function(options) {
return dbapi.saveUserAccessToken(user.email, { return dbapi.saveUserAccessToken(user.email, {
title: title title: title
, tokenId: tokenId , id: tokenId
, jwt: jwt , jwt: jwt
}) })
.then(function() { .then(function() {
socket.emit('user.keys.accessToken.generated', { socket.emit('user.keys.accessToken.generated', {
title: title title: title
, tokenId: tokenId , tokenId: tokenId
, jwt: jwt
}) })
}) })
}) })

View file

@ -0,0 +1,35 @@
module.exports = function AccessTokenServiceFactory(
$rootScope
, $http
, socket
) {
var AccessTokenService = {}
AccessTokenService.getAccessTokens = function() {
return $http.get('/app/api/v1/accessTokens')
}
AccessTokenService.generateAccessToken = function(title) {
socket.emit('user.keys.accessToken.generate', {
title: title
})
}
AccessTokenService.removeAccessToken = function(title) {
socket.emit('user.keys.accessToken.remove', {
title: title
})
}
socket.on('user.keys.accessToken.generated', function(token) {
$rootScope.$broadcast('user.keys.accessTokens.generated', token)
$rootScope.$apply()
})
socket.on('user.keys.accessToken.removed', function() {
$rootScope.$broadcast('user.keys.accessTokens.updated')
$rootScope.$apply()
})
return AccessTokenService
}

View file

@ -4,16 +4,15 @@ module.exports = function generateAccessTokenDirective() {
replace: true, replace: true,
scope: { scope: {
showGenerate: '=', showGenerate: '=',
showClipboard: '=',
}, },
template: require('./generate-access-token.jade'), template: require('./generate-access-token.jade'),
controller: function($scope, UserService) { controller: function($scope, AccessTokenService) {
$scope.generateForm = { $scope.generateForm = {
title: '' title: ''
} }
$scope.generateToken = function () { $scope.generateToken = function () {
UserService.generateAccessToken($scope.generateForm.title) AccessTokenService.generateAccessToken($scope.generateForm.title)
$scope.closeGenerateToken() $scope.closeGenerateToken()
} }

View file

@ -1,3 +1,4 @@
module.exports = angular.module('stf.tokens', [ module.exports = angular.module('stf.tokens', [
require('./generate-access-token').name, require('./generate-access-token').name,
]) ])
.factory('AccessTokenService', require('./access-token-service'))

View file

@ -8,22 +8,6 @@ module.exports = function UserServiceFactory(
var user = UserService.currentUser = AppState.user var user = UserService.currentUser = AppState.user
UserService.getAccessTokens = function() {
return (user.accessTokens || (user.accessTokens = []))
}
UserService.generateAccessToken = function(title) {
socket.emit('user.keys.accessToken.generate', {
title: title
})
}
UserService.removeAccessToken = function(title) {
socket.emit('user.keys.accessToken.remove', {
title: title
})
}
UserService.getAdbKeys = function() { UserService.getAdbKeys = function() {
return (user.adbKeys || (user.adbKeys = [])) return (user.adbKeys || (user.adbKeys = []))
} }
@ -40,26 +24,6 @@ module.exports = function UserServiceFactory(
socket.emit('user.keys.adb.remove', key) socket.emit('user.keys.adb.remove', key)
} }
// socket.on('user.keys.accessToken.generated', function(token) {
// UserService.getAccessTokens().push(token)
// $rootScope.$broadcast('user.keys.accessTokens.updated', user.accessTokens)
// $rootScope.$apply()
// })
socket.on('user.keys.accessToken.generated', function(token) {
$rootScope.$broadcast('user.keys.accessTokens.generated', token)
$rootScope.$apply()
})
socket.on('user.keys.accessToken.removed', function(title) {
user.accessTokens = UserService.getAccessTokens().filter(function(token) {
return token.title !== title
})
$rootScope.$broadcast('user.keys.accessTokens.updated', user.accessTokens)
$rootScope.$apply()
})
socket.on('user.keys.adb.added', function(key) { socket.on('user.keys.adb.added', function(key) {
UserService.getAdbKeys().push(key) UserService.getAdbKeys().push(key)
$rootScope.$broadcast('user.keys.adb.updated', user.adbKeys) $rootScope.$broadcast('user.keys.adb.updated', user.adbKeys)

View file

@ -1,28 +1,28 @@
module.exports = function AccessTokensCtrl($scope, $http, UserService) { module.exports = function AccessTokensCtrl($scope, AccessTokenService) {
$scope.accessTokens = [] $scope.accessTokenTitles = []
$scope.newToken = null $scope.newToken = null
function updateTokens() { function updateTokens() {
$scope.accessTokens = UserService.getAccessTokens() AccessTokenService.getAccessTokens()
.success(function(response) {
$scope.accessTokenTitles = response.titles || []
})
} }
$scope.removeToken = function (title) { $scope.removeToken = function (title) {
UserService.removeAccessToken(title) AccessTokenService.removeAccessToken(title)
} }
$scope.tokenGenerated = function() { $scope.closeGenerated = function() {
$scope.accessToken = ''
$scope.showGenerated = false $scope.showGenerated = false
UserService.getAccessTokens().push($scope.newToken)
$scope.newToken = null $scope.newToken = null
updateTokens() updateTokens()
} }
$scope.$on('user.keys.accessTokens.generated', function(event, token) { $scope.$on('user.keys.accessTokens.generated', function(event, token) {
$scope.showGenerated = true
$scope.accessTokenId = token.tokenId
$scope.newToken = token $scope.newToken = token
$scope.showGenerated = true
}) })
$scope.$on('user.keys.accessTokens.updated', updateTokens) $scope.$on('user.keys.accessTokens.updated', updateTokens)

View file

@ -14,7 +14,7 @@
.widget-content.padded .widget-content.padded
nothing-to-show(icon='fa-key', message='{{"No access tokens" | translate}}', nothing-to-show(icon='fa-key', message='{{"No access tokens" | translate}}',
ng-if='!accessTokens.length && !showGenerate && !showGenerated') ng-if='!accessTokenTitles.length && !showGenerate && !showGenerated')
generate-access-token(show-clipboard='true', show-generate='showGenerate') generate-access-token(show-clipboard='true', show-generate='showGenerate')
@ -24,17 +24,17 @@
span   span  
span(translate) Make sure to copy your access token now. You won't be able to see it again! span(translate) Make sure to copy your access token now. You won't be able to see it again!
br br
button.btn.pull-right.btn-primary.btn-sm(ng-click='tokenGenerated()') button.btn.pull-right.btn-primary.btn-sm(ng-click='closeGenerated()')
i.fa.fa-check.fa-fw i.fa.fa-check.fa-fw
textarea(readonly, rows='1', text-focus-select, ng-model='accessTokenId').form-control.token-id-textarea textarea(readonly, rows='1', text-focus-select, ng-model='newToken.tokenId').form-control.token-id-textarea
ul.list-group.key-list ul.list-group.key-list
li.list-group-item(ng-repeat='token in accessTokens').animate-repeat li.list-group-item(ng-repeat='title in accessTokenTitles').animate-repeat
a a
i.fa.fa-key.fa-2x.fa-fw.key-list-icon i.fa.fa-key.fa-2x.fa-fw.key-list-icon
.key-list-details.selectable .key-list-details.selectable
.key-list-title(ng-bind='token.title') .key-list-title(ng-bind='title')
button.btn.btn-xs.btn-danger-outline.pull-right.key-list-remove(ng-click='removeToken(token.title)') button.btn.btn-xs.btn-danger-outline.pull-right.key-list-remove(ng-click='removeToken(title)')
i.fa.fa-trash-o i.fa.fa-trash-o
span(translate) Remove span(translate) Remove

View file

@ -2,6 +2,7 @@ require('./access-tokens.css')
module.exports = angular.module('stf.settings.keys.access-tokens', [ module.exports = angular.module('stf.settings.keys.access-tokens', [
require('stf/common-ui').name, require('stf/common-ui').name,
require('stf/tokens').name,
require('stf/tokens/generate-access-token').name require('stf/tokens/generate-access-token').name
]) ])
.run(["$templateCache", function ($templateCache) { .run(["$templateCache", function ($templateCache) {