2015-07-20 00:09:47 -07:00
<!-- Modal change password -->
< div class = "modal fade" id = "passwordChangeModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Change Your Password< / h4 >
< / div >
< div class = "modal-body" >
2016-02-25 14:58:26 +01:00
< form name = "passwordChangeForm" role = "form" novalidate ng-submit = "passwordchange.submit()" autocomplete = "off" >
2016-02-25 14:46:53 +01:00
< input type = "password" style = "display: none;" >
< div class = "form-group" ng-class = "{ 'has-error': (!passwordChangeForm.password.$dirty && passwordchange.error.password) || (passwordChangeForm.password.$dirty && passwordChangeForm.password.$invalid) }" >
< label class = "control-label" for = "inputPasswordChangePassword" > Current Password< / label >
< div class = "control-label" ng-show = "(!passwordChangeForm.password.$dirty && passwordchange.error.password) || (passwordChangeForm.password.$dirty && passwordChangeForm.password.$invalid)" >
< small ng-show = "!passwordChangeForm.password.$dirty && passwordchange.error.password" > Wrong password< / small >
< small ng-show = "passwordChangeForm.password.$dirty && passwordChangeForm.password.$error.required" > A password is required< / small >
2015-07-20 00:09:47 -07:00
< / div >
2016-02-25 14:46:53 +01:00
< input type = "password" class = "form-control" ng-model = "passwordchange.password" id = "inputPasswordChangePassword" name = "password" required autofocus >
< / div >
< div class = "form-group" ng-class = "{ 'has-error': (!passwordChangeForm.newPassword.$dirty && passwordchange.error.newPassword) || (passwordChangeForm.newPassword.$dirty && passwordChangeForm.newPassword.$invalid) }" >
< label class = "control-label" for = "inputPasswordChangeNewPassword" > New Password< / label >
< div class = "control-label" ng-show = "(!passwordChangeForm.newPassword.$dirty && passwordchange.error.newPassword) || (passwordChangeForm.newPassword.$dirty && passwordChangeForm.newPassword.$invalid)" >
< small ng-show = "!passwordChangeForm.newPassword.$dirty && passwordchange.error.newPassword" > {{ passwordchange.error.newPassword }}< br / > < br / > < / small >
< small ng-show = " passwordChangeForm.newPassword.$dirty && passwordChangeForm.newPassword.$invalid" > Password must be 8-30 character with at least one uppercase, one numeric and one special character< / small >
2015-07-20 00:09:47 -07:00
< / div >
2016-02-25 14:46:53 +01:00
< input type = "password" class = "form-control" ng-model = "passwordchange.newPassword" id = "inputPasswordChangeNewPassword" name = "newPassword" ng-pattern = "/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,30}$/" required autofocus >
< / div >
< div class = "form-group" ng-class = "{ 'has-error': (!passwordChangeForm.newPassword.$dirty && passwordchange.error.newPassword) || (passwordChangeForm.newPasswordRepeat.$dirty && passwordChangeForm.newPasswordRepeat.$error.required) || (passwordChangeForm.newPasswordRepeat.$dirty && passwordchange.newPassword !== passwordchange.newPasswordRepeat) }" >
< label class = "control-label" for = "inputPasswordChangeNewPasswordRepeat" > Repeat New Password< / label >
< div class = "control-label" ng-show = "(!passwordChangeForm.newPassword.$dirty && passwordchange.error.newPassword) || (passwordChangeForm.newPasswordRepeat.$dirty && passwordChangeForm.newPasswordRepeat.$error.required) || (passwordChangeForm.newPasswordRepeat.$dirty && passwordchange.newPassword !== passwordchange.newPasswordRepeat)" >
< small ng-show = "passwordChangeForm.newPasswordRepeat.$dirty && passwordChangeForm.newPasswordRepeat.$error.required" > A password is required< / small >
< small ng-show = "passwordChangeForm.newPasswordRepeat.$dirty && passwordchange.newPassword !== passwordchange.newPasswordRepeat && passwordchange.newPasswordRepeat" > Passwords don't match< / small >
2015-07-20 00:09:47 -07:00
< / div >
2016-02-25 14:46:53 +01:00
< input type = "password" class = "form-control" ng-model = "passwordchange.newPasswordRepeat" id = "inputPasswordChangeNewPasswordRepeat" name = "newPasswordRepeat" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "passwordChangeForm.$invalid" / >
2016-02-25 14:58:26 +01:00
< / form >
2015-07-20 00:09:47 -07:00
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2016-02-25 14:58:26 +01:00
< button type = "button" class = "btn btn-danger" ng-click = "passwordchange.submit()" ng-disabled = "passwordChangeForm.$invalid || passwordchange.busy" > < i class = "fa fa-spinner fa-pulse" ng-show = "passwordchange.busy" > < / i > Change< / button >
2015-07-20 00:09:47 -07:00
< / div >
< / div >
< / div >
< / div >
<!-- Modal change email -->
< div class = "modal fade" id = "emailChangeModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Change Your Email< / h4 >
< / div >
< div class = "modal-body" >
2016-02-25 14:58:26 +01:00
< form name = "emailChangeForm" role = "form" novalidate ng-submit = "emailchange.submit()" autocomplete = "off" >
2016-02-25 14:46:53 +01:00
< div class = "form-group" ng-class = "{ 'has-error': (emailChangeForm.email.$dirty && emailChangeForm.email.$invalid) }" >
2016-02-25 14:34:16 +01:00
< label class = "control-label" for = "inputEmailChangeEmail" > New Email Address< / label >
2016-02-25 14:46:53 +01:00
< div class = "control-label" ng-show = "(!emailChangeForm.email.$dirty && emailchange.error.email) || (emailChangeForm.email.$dirty && emailChangeForm.email.$invalid)" >
< small ng-show = "emailChangeForm.email.$error.required" > A valid email address is required< / small >
< small ng-show = "(emailChangeForm.email.$dirty && emailChangeForm.email.$invalid) && !emailChangeForm.email.$error.required" > The Email address is not valid< / small >
2015-07-20 00:09:47 -07:00
< / div >
2016-02-25 14:34:16 +01:00
< input type = "email" class = "form-control" ng-model = "emailchange.email" id = "inputEmailChangeEmail" name = "email" required autofocus >
< / div >
2016-02-25 14:46:53 +01:00
< input class = "ng-hide" type = "submit" ng-disabled = "emailChangeForm.$invalid" / >
2015-07-20 00:09:47 -07:00
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2016-02-25 14:58:26 +01:00
< button type = "button" class = "btn btn-success" ng-click = "emailchange.submit()" ng-disabled = "emailChangeForm.$invalid || emailchange.busy" > < i class = "fa fa-spinner fa-pulse" ng-show = "emailchange.busy" > < / i > Change< / button >
2015-07-20 00:09:47 -07:00
< / div >
< / div >
< / div >
< / div >
2016-02-25 15:09:52 +01:00
<!-- Modal change displayName -->
< div class = "modal fade" id = "displayNameChangeModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Change Your Display Name< / h4 >
< / div >
< div class = "modal-body" >
< form name = "displayNameChangeForm" role = "form" novalidate ng-submit = "displayNameChange.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (displayNameChangeForm.displayName.$dirty && displayNameChangeForm.displayName.$invalid) }" >
< label class = "control-label" > Display Name< / label >
< div class = "control-label" ng-show = "(!displayNameChangeForm.displayName.$dirty && displayNameChange.error.displayName) || (displayNameChangeForm.displayName.$dirty && displayNameChangeForm.displayName.$invalid)" >
< small ng-show = "displayNameChangeForm.displayName.$error.required" > A valid display name is required< / small >
< small ng-show = "(displayNameChangeForm.displayName.$dirty && displayNameChangeForm.displayName.$invalid) && !displayNameChangeForm.displayName.$error.required" > This display name is not valid< / small >
< / div >
< input type = "text" class = "form-control" ng-model = "displayNameChange.displayName" name = "displayName" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "displayNameChangeForm.$invalid" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
< button type = "button" class = "btn btn-success" ng-click = "displayNameChange.submit()" ng-disabled = "displayNameChangeForm.$invalid || displayNameChange.busy" > < i class = "fa fa-spinner fa-pulse" ng-show = "displayNameChange.busy" > < / i > Change< / button >
< / div >
< / div >
< / div >
< / div >
2016-06-07 10:42:54 +02:00
<!-- Modal add client -->
< div class = "modal fade" id = "clientAddModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Add API Client< / h4 >
< / div >
< div class = "modal-body" >
< form name = "clientAddForm" role = "form" novalidate ng-submit = "clientAdd.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (clientAddForm.name.$dirty && clientAddForm.name.$invalid) || (!clientAddForm.name.$dirty && clientAdd.error.name) }" >
< label class = "control-label" > Name< / label >
< div class = "control-label" ng-show = "(!clientAddForm.name.$dirty && clientAdd.error.name) || (clientAddForm.name.$dirty && clientAddForm.name.$invalid)" >
< small ng-show = "clientAddForm.name.$error.required" > A name is required< / small >
< small ng-show = "!clientAddForm.name.$dirty && clientAdd.error.name" > {{ clientAdd.error.name }}< / small >
< / div >
< input type = "text" class = "form-control" ng-model = "clientAdd.name" name = "name" required autofocus >
< / div >
< div class = "form-group" ng-class = "{ 'has-error': (clientAddForm.scope.$dirty && clientAddForm.scope.$invalid) || (!clientAddForm.scope.$dirty && clientAdd.error.scope) }" >
< label class = "control-label" > Scope< / label >
< div class = "control-label" ng-show = "(!clientAddForm.scope.$dirty && clientAdd.error.scope) || (clientAddForm.scope.$dirty && clientAddForm.scope.$invalid)" >
< small ng-show = "clientAddForm.scope.$error.required" > A scope is required< / small >
< small ng-show = "!clientAddForm.scope.$dirty && clientAdd.error.scope" > {{ clientAdd.error.scope }}< / small >
< / div >
< input type = "text" class = "form-control" ng-model = "clientAdd.scope" name = "scope" required >
< / div >
< div class = "form-group" ng-class = "{ 'has-error': (clientAddForm.redirectURI.$dirty && clientAddForm.redirectURI.$invalid) || (!clientAddForm.redirectURI.$dirty && clientAdd.error.redirectURI) }" >
< label class = "control-label" > Redirect URI< / label >
< div class = "control-label" ng-show = "!clientAddForm.redirectURI.$dirty && clientAdd.error.redirectURI" >
< small ng-show = "!clientAddForm.redirectURI.$dirty && clientAdd.error.redirectURI" > {{ clientAdd.error.redirectURI }}< / small >
< / div >
2016-06-07 10:55:36 +02:00
< input type = "text" class = "form-control" ng-model = "clientAdd.redirectURI" name = "redirectURI" id = "clientAddRedirectURI" placeholder = "Only required if OAuth logins are used" >
2016-06-07 10:42:54 +02:00
< / div >
< input class = "hide" type = "submit" ng-disabled = "clientAddForm.$invalid || clientAdd.busy" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
< button type = "button" class = "btn btn-success" ng-click = "clientAdd.submit()" ng-disabled = "clientAddForm.$invalid || clientAdd.busy" > < i class = "fa fa-spinner fa-pulse" ng-show = "clientAdd.busy" > < / i > Add API Client< / button >
< / div >
< / div >
< / div >
< / div >
2015-08-12 13:48:55 +02:00
< br / >
2016-06-07 10:10:58 +02:00
< div class = "section-header" >
2015-07-20 00:09:47 -07:00
< div class = "text-left" >
< h1 > Account< / h1 >
< / div >
< / div >
< div class = "card" >
< div class = "grid-item-top" >
< div class = "row" >
< div class = "col-xs-4" style = "min-width: 150px;" >
< img width = "128" height = "128" ng-src = "{{ user.gravatarHuge }}" / >
< / div >
< div class = "col-xs-8 text-medium" >
< table width = "100%" >
< tr >
< td class = "text-muted" style = "vertical-align: top;" > Username< / td >
2016-02-25 15:09:52 +01:00
< td class = "text-right" style = "vertical-align: top;" > {{ user.username }} < / td >
< / tr >
< tr >
< td class = "text-muted" style = "vertical-align: top;" > Display Name< / td >
< td class = "text-right" style = "vertical-align: top; white-space: nowrap;" > {{ user.displayName }} < a href = "" ng-click = "displayNameChange.show()" > < i class = "fa fa-pencil text-small" > < / i > < / a > < / td >
2015-07-20 00:09:47 -07:00
< / tr >
< tr >
< td class = "text-muted" style = "vertical-align: top;" > Email< / td >
2016-02-25 14:58:26 +01:00
< td class = "text-right" style = "vertical-align: top; white-space: nowrap;" > {{ user.email }} < a href = "" ng-click = "emailchange.show()" > < i class = "fa fa-pencil text-small" > < / i > < / a > < / td >
2015-07-20 00:09:47 -07:00
< / tr >
< tr >
< td class = "text-right" colspan = "2" style = "vertical-align: top;" >
< br / >
2016-05-06 14:38:17 +02:00
< button class = "btn btn-outline btn-xs btn-default" ng-click = "showTutorial()" > Show Tutorial< / button >
2016-02-25 14:58:26 +01:00
< button class = "btn btn-outline btn-xs btn-danger" ng-click = "passwordchange.show()" > Change Password< / button >
2015-07-20 00:09:47 -07:00
< / td >
< / tr >
< / table >
< / div >
< / div >
< / div >
< / div >
2016-06-07 10:42:54 +02:00
< br / >
2016-06-07 10:10:58 +02:00
< div class = "section-header" >
2015-07-20 00:09:47 -07:00
< div class = "text-left" >
2016-06-07 10:42:54 +02:00
< h3 > Application and API Access < button class = "btn btn-primary btn-outline pull-right" ng-click = "clientAdd.show()" > < i class = "fa fa-plus" > < / i > New API Client< / button > < / h3 >
2015-07-20 00:09:47 -07:00
< / div >
< / div >
2016-06-07 10:42:54 +02:00
< br / >
2015-07-20 00:09:47 -07:00
<!-- we will always at least have the webadmin token here, so activeClients always will have one entry with at least one token -->
2016-06-07 10:55:36 +02:00
< div class = "card" ng-repeat = "client in activeClients" >
2015-07-20 00:09:47 -07:00
< div class = "grid-item-top" >
< div class = "row" >
< div class = "col-xs-12" >
2016-06-07 12:28:33 +02:00
< h4 class = "text-muted" > {{client.name}} < span ng-show = "client.location !== 'external'" > on {{client.location}}{{ config.isCustomDomain ? '.' : '-' }}{{config.fqdn}}< / span > < / h4 >
2015-07-20 00:09:47 -07:00
< / div >
< / div >
< div class = "row" >
< div class = "col-xs-12" >
< div class = "row" >
< div class = "col-xs-12" >
2016-06-07 12:37:18 +02:00
You logged in < b > {{ client.activeTokens.length }}< / b > times to this application.
< button class = "btn btn-xs btn-danger pull-right" ng-click = "removeAccessTokens(client)" ng-disabled = "!client.activeTokens.length || client.busy" > < i class = "fa fa-spinner fa-pulse" ng-show = "client.busy" > < / i > Remove access< / button >
2015-07-20 00:09:47 -07:00
< br / >
2016-06-07 12:28:33 +02:00
< a href = "" data-toggle = "collapse" data-parent = "#accordion" data-target = "#collapse{{client.id}}" ng-show = "user.admin" > Advanced< / a >
2015-07-20 00:09:47 -07:00
< div id = "collapse{{client.id}}" class = "panel-collapse collapse" >
< div class = "panel-body" >
< h4 class = "text-muted" > Credentials< / h4 >
< p > Permissions: < b > {{ client.scope }}< / b > < / p >
< p > Client ID: < b > {{ client.id }}< / b > < / p >
2015-10-16 19:41:50 +02:00
< p ng-show = "client.clientSecret" > Client Secret: < b > {{ client.clientSecret }}< / b > < / p >
2015-07-20 00:09:47 -07:00
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >