Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(device): add transfer capabilties #446

Merged
merged 12 commits into from
Sep 6, 2022
1 change: 1 addition & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@
<script src="scripts/controllers/account.box.edit.script.js"></script>
<script src="scripts/controllers/account.box.edit.mqtt.js"></script>
<script src="scripts/controllers/account.box.edit.ttn.js"></script>
<script src="scripts/controllers/account.box.edit.transfer.js"></script>
<script src="scripts/controllers/account.box.dataupload.js"></script>
<script src="scripts/services/account.js"></script>
<script src="scripts/services/directus.js"></script>
Expand Down
10 changes: 10 additions & 0 deletions app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,16 @@
},
},
})
.state('account.edit.transfer', {
url: '/transfer',
views: {
edit: {
controller: 'EditBoxTransferController',
controllerAs: 'transfer',
templateUrl: 'views/account.box.edit.transfer.html',
},
},
})
.state('account.dashboard', {
url: '',
views: {
Expand Down
79 changes: 79 additions & 0 deletions app/scripts/controllers/account.box.edit.transfer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
(function () {
'use strict';

angular
.module('openSenseMapApp')
.controller('EditBoxTransferController', EditBoxTransferController);

EditBoxTransferController.$inject = ['boxData', 'moment', 'AccountService'];

function EditBoxTransferController (boxData, moment, AccountService) {
var vm = this;
vm.device = {};
vm.deviceName = '';
vm.data = {};
vm.tokenExists = false;
vm.expiration = '1';

vm.transferDevice = transferDevice;
vm.revokeToken = revokeToken;

activate();

////

function activate () {
if (angular.isDefined(boxData)) {
angular.copy(boxData, vm.device);

return AccountService.getTransferToken(vm.device._id)
.then(function (response) {
if (response.data) {
angular.copy(response.data, vm.data);
vm.tokenExists = true;
}
})
.catch(function (error) {
console.log(error);
});
}
}

function transferDevice () {

var payload = {
boxId: vm.device._id,
date: moment.utc().add(vm.expiration, 'd')
.toDate()
};

return AccountService.transferDevice(payload)
.then(function (response) {
angular.copy(response.data, vm.data);
vm.tokenExists = true;
})
.catch(function (error) {
console.log(error);
});
}

function revokeToken () {
var payload = {
boxId: vm.device._id,
token: vm.data.token
};

return AccountService.revokeToken(payload)
.then(function (response) {
if (response.status === 204) {
angular.copy({}, vm.data);
vm.tokenExists = false;
}
})
.catch(function (error) {
console.log(error);
});
}

}
})();
34 changes: 34 additions & 0 deletions app/scripts/controllers/account.dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
vm.boxes = [];
vm.listStyle = 'tiles';
vm.orderByProperty = 'createdAt';
vm.claimToken = '';
vm.claimPattern = /^[a-z0-9]*$/;
vm.errorMessage = '';

vm.claimDevice = claimDevice;
vm.closeAlert = closeAlert;

activate();

Expand Down Expand Up @@ -47,6 +53,34 @@
});
}

function claimDevice () {
var payload = {
token: vm.claimToken
};



return AccountService.claimDevice(payload)
.then(function () {

// Clear token field
vm.claimToken = '';

return getUsersBoxes()
.then(function () {
// console.log('refreshed boxes');
});
})
.catch(function (error) {
console.log(error);
vm.errorMessage = error.message;
});
}

function closeAlert () {
vm.errorMessage = '';
}

$scope.$watch('dashboard.listStyle', function (value) {
LocalStorageService.setValue(localStorageKey, value);
});
Expand Down
52 changes: 51 additions & 1 deletion app/scripts/services/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
deleteMeasurement: deleteMeasurement,
postNewBox: postNewBox,
deleteAccount: deleteAccount,
compileSketch: compileSketch
compileSketch: compileSketch,
transferDevice: transferDevice,
revokeToken: revokeToken,
getTransferToken: getTransferToken,
claimDevice: claimDevice
};

return service;
Expand Down Expand Up @@ -246,5 +250,51 @@
})
.catch(failed);
}

function getTransferToken (boxId) {
return $http
.get(app.API_URL + '/boxes/transfer/' + boxId, {
auth: true,
})
.then(function (response) {
return response.data;
})
.catch(failed);
}

function transferDevice (data) {
return $http.post(app.API_URL + '/boxes/transfer', data, {
auth: true,
})
.then(function (response) {
return response.data;
})
.catch(failed);
}

function revokeToken (data) {
return $http
.delete(app.API_URL + '/boxes/transfer', {
auth: true,
data: data,
headers: {
'Content-type': 'application/json;charset=utf-8',
},
})
.then(function (response) {
return response;
})
.catch(failed);
}

function claimDevice (data) {
return $http.post(app.API_URL + '/boxes/claim', data, {
auth: true
})
.then(function (response) {
return response.data;
})
.catch(failed);
}
}
})();
1 change: 1 addition & 0 deletions app/scripts/services/authenticationInterceptor.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
});

return deferred.promise;
case 400:
case 404:
return $q.reject(response);
default:
Expand Down
1 change: 1 addition & 0 deletions app/views/account.box.edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<li ng-class="{'active': edit.tabActive.script}" ng-click="edit.changeActiveTab('script')"><a ui-sref="account.edit.script"><i class="fa fa-file-text-o fa-fw"></i> {{'EDIT_SCRIPT'|translate}}</a></li>
<li ng-class="{'active': edit.tabActive.mqtt}" ng-click="edit.changeActiveTab('mqtt')"><a ui-sref="account.edit.mqtt"><i class="fa fa-wifi fa-fw"></i> {{'EDIT_MQTTOPTIONS'|translate}}</a></li>
<li ng-class="{'active': edit.tabActive.ttn}" ng-click="edit.changeActiveTab('ttn')"><a ui-sref="account.edit.ttn"><i class="fa fa-cloud-upload fa-fw"></i> {{'EDIT_TTN'|translate}}</a></li>
<li ng-class="{'active': edit.tabActive.transfer}" ng-click="edit.changeActiveTab('transfer')"><a ui-sref="account.edit.transfer"><i class="fa fa-exchange fa-fw"></i> {{'EDIT_TRANSFER'|translate}}</a></li>
</ul>
</div>
<div class="col-lg-9 col-md-9">
Expand Down
62 changes: 62 additions & 0 deletions app/views/account.box.edit.transfer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<div class="transferSettings">
<div class="row">
<div class="col-md-6 col-lg-6">
<h2 style="margin-top: 0px; margin-bottom: 0px">{{'EDIT_TRANSFER'|translate}}</h2>
</div>
</div>

<hr>

<div class="row">
<div class="col-md-6 col-lg-6">

<div uib-alert class="alert-warning">
<p>
<span class="fa fa-exclamation-circle" aria-hidden="true"></span>
{{'TRANSFER_NOTICE' | translate}}
</p>
<hr>
<p ng-bind-html="'TRANSFER_INFORMATION'|translate"></p>
</div>

<div ng-show="transfer.tokenExists" style="border: 1px solid grey; border-radius: 6px;">
<div style="min-height: inherit; padding: 8px; box-sizing: border-box;">
<div style="display: flex; float: right; box-sizing: border-box;">
<button ng-click="transfer.revokeToken()" class="btn btn-danger">{{'REVOKE' | translate}}</button>
</div>
<small style="margin-right: 8px; float: right;">
{{'CREATED_AT' | translate}}: {{transfer.data.createdAt | amUtc | amLocal | amDateFormat:'l LTS'}}
</small>
<span>Token:</span>
<code>{{transfer.data.token}} <button osem-clipboard class="btn-toClipboard" text="transfer.data.token" title="Copy to Clipboard"><i class="fa fa-clipboard"></i></button></code>
<div>
<span>{{'EXPIRES_AT' | translate}}: {{transfer.data.expiresAt | amUtc | amLocal | amDateFormat:'l LTS'}}</span>
</div>
</div>
</div>

<div ng-hide="transfer.tokenExists">
<form name="tokenForm" novalidate>
<div class="form-group">
<label for="expiration">{{'EXPIRATION' | translate}}</label>
<select class="form-control" ng-model="transfer.expiration" ng-change="transfer.changeExpiration()" name="expiration" id="expiration">
<option value="1">1 {{'DAY' | translate}}</option>
<option value="7">7 {{'DAYS' | translate}}</option>
<option value="30">30 {{'DAYS' | translate}}</option>
<option value="60">60 {{'DAYS' | translate}}</option>
<option value="90">90 {{'DAYS' | translate}}</option>
</select>
</div>
<div class="form-group" >
<label class="control-label" translate="TRANSFER_INPUT_LABEL" translate-value-name="{{transfer.device.name}}"></label>
<input type="text" name="name" id="name" class="form-control" ng-model="transfer.deviceName" required>
</div>
<div class="form-group">
<button ng-disabled="transfer.deviceName !== transfer.device.name" ng-click="transfer.transferDevice()" class="btn btn-danger col-md-12">{{'TRANSFER_BUTTON_TEXT' | translate}}</button>
</div>
</form>
</div>
</div>
</div>

</div>
38 changes: 34 additions & 4 deletions app/views/account.dashboard.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<div class="container">
<div class="row">
<div class="col-lg-12 col-sm-12 col-md-12" style="padding-top: 15px;">
<div class="thumbnail">
<!-- First row with stats and token transfer -->
<div class="row" style="display: flex; flex-wrap: wrap;">
<div class="col-lg-6 col-sm-12 col-md-12" style="margin-bottom: 30px;">
<div class="thumbnail" style="height: 100%;">
<div class="caption">
<h3 translate="REGISTERED_BOXES" translate-values="{count: dashboard.boxes.length}"></h3>
<p>{{'REGISTERED_BOXES_INFO' | translate}}</p>
Expand All @@ -16,6 +17,35 @@ <h3 translate="REGISTERED_BOXES" translate-values="{count: dashboard.boxes.lengt
</div>
</div>

<div class="col-lg-6 col-sm-12 col-md-12" style="margin-bottom: 30px;">
<div class="thumbnail" style="height: 100%;">
<div class="caption">
<h3>{{'CLAIM_HEADER' | translate}}</h3>
<form name="claimForm" novalidate>
<div class="form-group">
<label for="token" ng-bind-html="'CLAIM_INFORMATION'|translate"></label>
<div class="input-group">
<input type="text" name="token" id="token" class="form-control" placeholder="Token" ng-model="dashboard.claimToken" ng-pattern="dashboard.claimPattern" maxlength="12">
<span class="input-group-btn">
<button class="btn btn-primary" type="button" ng-click="dashboard.claimDevice()" ng-disabled="dashboard.claimToken === ''">{{'CLAIM_DEVICE' | translate}}</button>
</span>
</div><!-- /input-group -->
<span class="help-block" ng-show="claimForm.token.$error.pattern">{{'CLAIM_VALID_TOKEN' | translate}}</span><br>
</div>
</form>
<div class="alert alert-danger alert-dismissible" role="alert" ng-show="dashboard.errorMessage">
<button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="dashboard.closeAlert()">
<span aria-hidden="true">&times;</span>
</button>
{{dashboard.errorMessage}}
</div>
</div>
</div>
</div>
</div>

<!-- Second row with options for device list -->
<div class="row">
<div class="col-sm-4 col-sm-offset-8 clearfix">
<div class="btn-group pull-right">
<label class="btn btn-default" ng-model="dashboard.listStyle" uib-btn-radio="'tiles'">
Expand All @@ -37,8 +67,8 @@ <h3 translate="REGISTERED_BOXES" translate-values="{count: dashboard.boxes.lengt
</button>
</div>
</div>

</div>

<div class="row" ng-show="dashboard.listStyle==='tiles'">
<div class="col-lg-6" ng-repeat="box in dashboard.boxes | orderBy: dashboard.orderByProperty"
style="padding-top: 15px;">
Expand Down