2018-01-22 13:01:38 -08: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" >
< form name = "passwordChangeForm" role = "form" novalidate ng-submit = "passwordchange.submit()" autocomplete = "off" >
< 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 >
< / div >
< 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 >
2018-06-11 13:48:12 -07:00
< small ng-show = " passwordChangeForm.newPassword.$dirty && passwordChangeForm.newPassword.$invalid" > Password must be atleast 8 characters< / small >
2018-01-22 13:01:38 -08:00
< / div >
2019-02-08 09:50:39 -08:00
< input type = "password" class = "form-control" ng-model = "passwordchange.newPassword" id = "inputPasswordChangeNewPassword" name = "newPassword" ng-pattern = "/^.{8,}$/" required autofocus >
2018-01-22 13:01:38 -08:00
< / 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 >
< / div >
< 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" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2018-11-16 17:03:21 +01:00
< button type = "button" class = "btn btn-danger" ng-click = "passwordchange.submit()" ng-disabled = "passwordChangeForm.$invalid || passwordchange.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "passwordchange.busy" > < / i > Change< / button >
2018-01-22 13:01:38 -08: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" >
2018-02-23 10:29:04 -08:00
< h4 class = "modal-title" > Change primary email address< / h4 >
2018-01-22 13:01:38 -08:00
< / div >
< div class = "modal-body" >
< form name = "emailChangeForm" role = "form" novalidate ng-submit = "emailchange.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (emailChangeForm.email.$dirty && emailChangeForm.email.$invalid) || (!emailChangeForm.email.$dirty && emailchange.error.email)}" >
< 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 >
< small ng-show = "!emailChangeForm.email.$dirty && emailchange.error.email" > {{ emailchange.error.email }}< / small >
< / div >
< input type = "email" class = "form-control" ng-model = "emailchange.email" id = "inputEmailChangeEmail" name = "email" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "emailChangeForm.$invalid" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2018-11-16 17:03:21 +01:00
< button type = "button" class = "btn btn-success" ng-click = "emailchange.submit()" ng-disabled = "emailChangeForm.$invalid || emailchange.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "emailchange.busy" > < / i > Change< / button >
2018-01-22 13:01:38 -08:00
< / div >
< / div >
< / div >
< / div >
<!-- Modal change fallback email -->
< div class = "modal fade" id = "fallbackEmailChangeModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Change password recovery email address< / h4 >
< / div >
< div class = "modal-body" >
< form name = "fallbackEmailChangeForm" role = "form" novalidate ng-submit = "fallbackEmailChange.submit()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (fallbackEmailChangeForm.email.$dirty && fallbackEmailChangeForm.email.$invalid) || (!fallbackEmailChangeForm.email.$dirty && fallbackEmailChange.error.email)}" >
< div class = "control-label" ng-show = "(!fallbackEmailChangeForm.email.$dirty && fallbackEmailChange.error.email) || (fallbackEmailChangeForm.email.$dirty && fallbackEmailChangeForm.email.$invalid)" >
< small ng-show = "fallbackEmailChangeForm.email.$error.required" > A valid email address is required< / small >
< small ng-show = "(fallbackEmailChangeForm.email.$dirty && fallbackEmailChangeForm.email.$invalid) && !fallbackEmailChangeForm.email.$error.required" > The Email address is not valid< / small >
< small ng-show = "!fallbackEmailChangeForm.email.$dirty && fallbackEmailChange.error.email" > {{ fallbackEmailChange.error.email }}< / small >
< / div >
< input type = "email" class = "form-control" ng-model = "fallbackEmailChange.email" id = "inputfallbackEmailChangeEmail" name = "email" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "fallbackEmailChangeForm.$invalid" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2018-11-16 17:03:21 +01:00
< button type = "button" class = "btn btn-success" ng-click = "fallbackEmailChange.submit()" ng-disabled = "fallbackEmailChangeForm.$invalid || fallbackEmailChange.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "fallbackEmailChange.busy" > < / i > Change< / button >
2018-01-22 13:01:38 -08:00
< / div >
< / div >
< / div >
< / div >
<!-- 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) || (!displayNameChangeForm.displayName.$dirty && displayNameChange.error.displayName)}" >
< 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 >
< small ng-show = "!displayNameChangeForm.email.$dirty && displayNameChange.error.displayName" > {{ displayNameChange.error.displayName }}< / small >
< / div >
< input type = "text" class = "form-control" ng-model = "displayNameChange.displayName" id = "inputDisplayNameChangeDisplayName" 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 >
2018-11-16 17:03:21 +01:00
< button type = "button" class = "btn btn-success" ng-click = "displayNameChange.submit()" ng-disabled = "displayNameChangeForm.$invalid || displayNameChange.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "displayNameChange.busy" > < / i > Change< / button >
2018-01-22 13:01:38 -08:00
< / div >
< / div >
< / div >
< / div >
2018-04-26 15:12:29 +02:00
<!-- Modal enable twofactor authentication -->
< div class = "modal fade" id = "twoFactorAuthenticationEnableModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Enable Two-Factor Authentication< / h4 >
< / div >
< div class = "modal-body text-center" ng-hide = "twoFactorAuthentication.secret" >
2018-11-16 17:03:21 +01:00
< h2 > < i class = "fa fa-circle-notch fa-spin" > < / i > < / h2 >
2018-04-26 15:12:29 +02:00
< / div >
< div class = "modal-body" ng-show = "twoFactorAuthentication.secret" >
2018-04-26 09:32:56 -07:00
< p >
Use Google Authenticator (< a href = "https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target = "_blank" > Android< / a > , < a href = "https://itunes.apple.com/us/app/google-authenticator/id388497605" target = "_blank" > iOS< / a > ), FreeOTP authenticator (< a href = "https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp" target = "_blank" > Android< / a > , < a href = "https://itunes.apple.com/us/app/freeotp-authenticator/id872559395" target = "_blank" > iOS< / a > ) or a similar TOTP app to scan the secret.
< / p >
2018-04-26 15:12:29 +02:00
< center >
< img ng-src = "{{ twoFactorAuthentication.qrcode }}" / >
< p > {{ twoFactorAuthentication.secret }}< / p >
< / center >
< br / >
< form name = "twoFactorAuthenticationEnableForm" role = "form" novalidate ng-submit = "twoFactorAuthentication.enable()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (!twoFactorAuthenticationEnableForm.totpToken.$dirty && twoFactorAuthentication.error) || (twoFactorAuthenticationEnableForm.totpToken.$dirty && twoFactorAuthenticationEnableForm.totpToken.$invalid) }" >
< label class = "control-label" > Token< / label >
< div class = "control-label" ng-show = "(!twoFactorAuthenticationEnableForm.totpToken.$dirty && twoFactorAuthentication.error) || (twoFactorAuthenticationEnableForm.totpToken.$dirty && twoFactorAuthenticationEnableForm.totpToken.$invalid)" >
< small > {{ twoFactorAuthentication.error }}< / small >
< / div >
< input type = "text" class = "form-control" ng-model = "twoFactorAuthentication.totpToken" id = "twoFactorAuthenticationTotpTokenInput" name = "totpToken" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "twoFactorAuthenticationEnableForm.$invalid" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2018-11-16 17:03:21 +01:00
< button type = "button" class = "btn btn-success" ng-click = "twoFactorAuthentication.enable()" ng-disabled = "twoFactorAuthenticationEnableForm.$invalid || twoFactorAuthentication.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "twoFactorAuthentication.busy" > < / i > Enable< / button >
2018-04-26 15:12:29 +02:00
< / div >
< / div >
< / div >
< / div >
2018-04-26 16:38:26 +02:00
<!-- Modal disable twofactor authentication -->
< div class = "modal fade" id = "twoFactorAuthenticationDisableModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Disable Two-Factor Authentication< / h4 >
< / div >
< div class = "modal-body" >
< form name = "twoFactorAuthenticationDisableForm" role = "form" novalidate ng-submit = "twoFactorAuthentication.disable()" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (!twoFactorAuthenticationDisableForm.password.$dirty && twoFactorAuthentication.error) || (twoFactorAuthenticationDisableForm.password.$dirty && twoFactorAuthenticationDisableForm.password.$invalid) }" >
< label class = "control-label" > Password< / label >
< div class = "control-label" ng-show = "(!twoFactorAuthenticationDisableForm.password.$dirty && twoFactorAuthentication.error) || (twoFactorAuthenticationDisableForm.password.$dirty && twoFactorAuthenticationDisableForm.password.$invalid)" >
< small > {{ twoFactorAuthentication.error }}< / small >
< / div >
< input type = "password" class = "form-control" ng-model = "twoFactorAuthentication.password" id = "twoFactorAuthenticationPasswordInput" name = "password" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "twoFactorAuthenticationDisableForm.$invalid" / >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2018-11-16 17:03:21 +01:00
< button type = "button" class = "btn btn-success" ng-click = "twoFactorAuthentication.disable()" ng-disabled = "twoFactorAuthenticationDisableForm.$invalid || twoFactorAuthentication.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "twoFactorAuthentication.busy" > < / i > Disable< / button >
2018-04-26 16:38:26 +02:00
< / div >
< / div >
< / div >
2018-08-27 15:26:52 -07:00
< / div >
<!-- Modal add token -->
< div class = "modal fade" id = "tokenAddModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2018-08-27 16:04:16 -07:00
< h4 class = "modal-title" > Create API token< / h4 >
< / div >
< div class = "modal-body" >
< div ng-hide = "tokenAdd.token.accessToken" >
< form name = "tokenAddForm" role = "form" novalidate ng-submit = "tokenAdd.submit(apiClient)" autocomplete = "off" >
< div class = "form-group" ng-class = "{ 'has-error': (tokenAddForm.tokenName.$dirty && tokenAddForm.tokenName.$invalid) || (!tokenAddForm.tokenName.$dirty && tokenAdd.error.tokenName)}" >
< label class = "control-label" > Token name< / label >
< div class = "control-label" ng-show = "(!tokenAddForm.tokenName.$dirty && tokenAdd.error.tokenName) || (tokenAddForm.tokenName.$dirty && tokenAddForm.tokenName.$invalid)" >
< small ng-show = "tokenAddForm.tokenName.$error.required" > A token name is required< / small >
< small ng-show = "(tokenAddForm.tokenName.$dirty && tokenAddForm.tokenName.$invalid) && !tokenAddForm.tokenName.$error.required" > This token name is not valid< / small >
< small ng-show = "!tokenAddForm.email.$dirty && tokenAdd.error.tokenName" > {{ tokenAdd.error.tokenName }}< / small >
< / div >
< input type = "text" class = "form-control" ng-model = "tokenAdd.tokenName" id = "inputTokenAddName" name = "tokenName" required autofocus >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "tokenAddForm.$invalid" / >
< / form >
< / div >
< div ng-show = "tokenAdd.token.accessToken" >
Use the following token to authenticate against the Cloudron API:
< br / >
< b ng-click-select > {{ tokenAdd.token.accessToken }}< / b >
< / div >
2018-08-27 15:26:52 -07:00
< / div >
< div class = "modal-footer" >
2018-08-27 16:04:16 -07:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Close< / button >
< button type = "button" class = "btn btn-success" ng-click = "tokenAdd.submit(apiClient)" ng-hide = "tokenAdd.token.accessToken" ng-disabled = "tokenAddForm.$invalid || tokenAdd.busy" >
2018-11-16 17:03:21 +01:00
< i class = "fa fa-circle-notch fa-spin" ng-show = "tokenAdd.busy" > < / i > Generate Token
2018-08-27 16:04:16 -07:00
< / button >
2018-08-27 15:26:52 -07:00
< / div >
< / div >
< / div >
< / div >
2018-04-26 16:38:26 +02:00
2018-01-22 13:01:38 -08:00
< div class = "content" >
< div class = "text-left" >
< h1 > Account< / h1 >
< / 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" >
< table width = "100%" >
< tr >
< td class = "text-muted" style = "vertical-align: top;" > Username< / td >
2018-04-26 16:32:43 +02:00
< td class = "text-right" style = "vertical-align: top;" >
{{ user.username }}
< / td >
2018-01-22 13:01:38 -08:00
< / tr >
< tr >
< td class = "text-muted" style = "vertical-align: top;" > Display name< / td >
2018-04-26 16:32:43 +02:00
< td class = "text-right" style = "vertical-align: top; white-space: nowrap;" >
2018-11-29 16:43:28 +01:00
{{ user.displayName }} < a href = "" ng-click = "displayNameChange.show()" > < i class = "fa fa-edit text-small" > < / i > < / a >
2018-04-26 16:32:43 +02:00
< / td >
2018-01-22 13:01:38 -08:00
< / tr >
< tr >
2018-02-23 10:29:04 -08:00
< td class = "text-muted" style = "vertical-align: top;" > Primary email< / td >
2018-04-26 16:32:43 +02:00
< td class = "text-right" style = "vertical-align: top; white-space: nowrap;" >
2018-11-29 16:43:28 +01:00
{{ user.email }} < a href = "" ng-click = "emailchange.show()" > < i class = "fa fa-edit text-small" > < / i > < / a >
2018-04-26 16:32:43 +02:00
< / td >
2018-01-22 13:01:38 -08:00
< / tr >
< tr >
< td class = "text-muted" style = "vertical-align: top;" > Password recovery email< / td >
2018-04-26 16:32:43 +02:00
< td class = "text-right" style = "vertical-align: top; white-space: nowrap;" >
2018-11-29 16:43:28 +01:00
{{ user.fallbackEmail }} < a href = "" ng-click = "fallbackEmailChange.show()" > < i class = "fa fa-edit text-small" > < / i > < / a >
2018-04-26 16:32:43 +02:00
< / td >
2018-01-22 13:01:38 -08:00
< / tr >
< tr >
< td class = "text-right" colspan = "2" style = "vertical-align: top;" >
< br / >
2018-04-26 09:56:10 -07:00
< button class = "btn btn-outline btn-xs btn-danger" ng-click = "twoFactorAuthentication.show()" > {{ user.twoFactorAuthenticationEnabled ? 'Disable' : 'Enable' }} 2FA< / button >
2018-01-22 13:01:38 -08:00
< button class = "btn btn-outline btn-xs btn-danger" ng-click = "passwordchange.show()" > Change Password< / button >
< / td >
< / tr >
< / table >
< / div >
< / div >
< / div >
< / div >
< br / >
2018-08-27 15:26:52 -07:00
< div class = "text-left" >
2018-08-27 15:34:46 -07:00
< h3 > API Tokens < button class = "btn btn-xs btn-primary btn-outline pull-right" ng-click = "tokenAdd.show(apiClient)" > < i class = "fa fa-plus" > < / i > New Token< / button > < / h3 >
2018-08-27 15:26:52 -07:00
< / div >
<!-- we will always at least have the webadmin token here, so activeClients always will have one entry with at least one token -->
< div class = "card" >
< div class = "grid-item-top" >
< div class = "row" >
< div class = "col-xs-12" >
< p > These tokens can be used to access the < a ng-href = "{{ config.webServerOrigin + '/developer/api/' }}" target = "_blank" > Cloudron API< / a > .< / p >
2018-08-27 15:34:46 -07:00
< table class = "table table-hover" >
< thead >
< tr >
< th style = "width:40%" > Name< / th >
< th style = "width:55%" class = "hidden-xs hidden-sm" > Token< / th >
< th style = "width: 5%" class = "text-right" > Actions< / th >
< / tr >
< / thead >
< tbody >
< tr ng-repeat = "token in apiClient.activeTokens" >
< td class = "text-left elide-table-cell" >
{{ token.name || '-' }}
< / td >
< td class = "text-left hand elide-table-cell hidden-xs hidden-sm" ng-click = "useredit.show(user)" >
< span ng-click-select > {{ token.accessToken }}< / span >
< / td >
< td class = "text-right no-wrap" style = "vertical-align: bottom" >
2018-11-15 18:07:18 +01:00
< button class = "btn btn-xs btn-danger pull-right" ng-click = "removeToken(apiClient, token)" title = "Revoke Token" > < i class = "far fa-trash-alt" > < / i > < / button >
2018-08-27 15:34:46 -07:00
< / td >
< / tr >
< / tbody >
< / table >
2018-08-27 15:26:52 -07:00
< / div >
< / div >
< / div >
< / div >
< br / >
2018-01-22 13:01:38 -08:00
< div class = "text-left" >
< h3 > Sessions< / h3 >
< / div >
< div class = "card" >
< div class = "grid-item-top" >
< div class = "row" >
< div class = "col-xs-12" >
< p > You are logged into {{ activeClients.length + 1 }} app(s), including this session.< / p >
< span ng-show = "activeTokenCount > 1" >
< hr / >
< h4 > Active Apps:< / h4 >
< p ng-repeat = "client in activeClients" > < b > {{ client.name }} - {{client.activeTokens.length}} time(s)< / b > < / p >
< hr / >
< / span >
< button class = "btn btn-outline btn-xs btn-danger pull-right" ng-click = "revokeTokens()" > Logout From All< / button >
< / div >
< / div >
< / div >
< / div >
2018-04-26 09:32:56 -07:00
< / div >