Move all front-end public field definitions into constructors for iOS support
This commit is contained in:
parent
251aa6cf97
commit
f06ff83dce
@ -38,14 +38,18 @@ export default class MFAChallengePage extends Component {
|
|||||||
static get props() { return ['app_name'] }
|
static get props() { return ['app_name'] }
|
||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
|
|
||||||
loading = false
|
constructor() {
|
||||||
|
super()
|
||||||
|
|
||||||
verify_code = ''
|
this.loading = false
|
||||||
verify_success = false
|
|
||||||
|
|
||||||
error_message = ''
|
this.verify_code = ''
|
||||||
other_message = ''
|
this.verify_success = false
|
||||||
t = {}
|
|
||||||
|
this.error_message = ''
|
||||||
|
this.other_message = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.t = await T(
|
this.t = await T(
|
||||||
|
@ -28,12 +28,16 @@ export default class MFADisableComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return [] }
|
static get props() { return [] }
|
||||||
|
|
||||||
app_name = ''
|
constructor() {
|
||||||
step = 0
|
super()
|
||||||
loading = false
|
|
||||||
error_message = ''
|
this.app_name = ''
|
||||||
other_message = ''
|
this.step = 0
|
||||||
t = {}
|
this.loading = false
|
||||||
|
this.error_message = ''
|
||||||
|
this.other_message = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.app_name = session.get('app.name')
|
this.app_name = session.get('app.name')
|
||||||
|
@ -38,12 +38,16 @@ export default class MFARecoveryComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return ['app_name'] }
|
static get props() { return ['app_name'] }
|
||||||
|
|
||||||
verify_success = false
|
constructor() {
|
||||||
loading = false
|
super()
|
||||||
recovery_code = ''
|
|
||||||
error_message = ''
|
this.verify_success = false
|
||||||
other_message = ''
|
this.loading = false
|
||||||
t = {}
|
this.recovery_code = ''
|
||||||
|
this.error_message = ''
|
||||||
|
this.other_message = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.t = await T(
|
this.t = await T(
|
||||||
|
@ -61,19 +61,23 @@ export default class MFASetupPage extends Component {
|
|||||||
static get props() { return ['app_name'] }
|
static get props() { return ['app_name'] }
|
||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
|
|
||||||
loading = false
|
constructor() {
|
||||||
step = 0
|
super()
|
||||||
|
|
||||||
qr_data = ''
|
this.loading = false
|
||||||
otpauth_url = ''
|
this.step = 0
|
||||||
secret = ''
|
|
||||||
verify_code = ''
|
|
||||||
|
|
||||||
verify_success = false
|
this.qr_data = ''
|
||||||
|
this.otpauth_url = ''
|
||||||
|
this.secret = ''
|
||||||
|
this.verify_code = ''
|
||||||
|
|
||||||
error_message = ''
|
this.verify_success = false
|
||||||
other_message = ''
|
|
||||||
t = {}
|
this.error_message = ''
|
||||||
|
this.other_message = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.t = await T(
|
this.t = await T(
|
||||||
|
@ -25,7 +25,11 @@ export default class AuthPage extends Component {
|
|||||||
static get props() { return ['app_name', 'message', 'actions'] }
|
static get props() { return ['app_name', 'message', 'actions'] }
|
||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
|
|
||||||
loading = false
|
constructor() {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
|
||||||
async action_click(index) {
|
async action_click(index) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
@ -78,23 +78,27 @@ export default class PasswordResetComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return ['app_name'] }
|
static get props() { return ['app_name'] }
|
||||||
|
|
||||||
step = 0
|
constructor() {
|
||||||
loading = false
|
super()
|
||||||
has_mfa = false
|
|
||||||
|
|
||||||
error_message = ''
|
this.step = 0
|
||||||
other_message = ''
|
this.loading = false
|
||||||
|
this.has_mfa = false
|
||||||
|
|
||||||
step_1_valid = false
|
this.error_message = ''
|
||||||
step_1_calc_time = ''
|
this.other_message = ''
|
||||||
step_1_problem = ''
|
|
||||||
|
|
||||||
step_2_valid = false
|
this.step_1_valid = false
|
||||||
|
this.step_1_calc_time = ''
|
||||||
|
this.step_1_problem = ''
|
||||||
|
|
||||||
password = ''
|
this.step_2_valid = false
|
||||||
confirm_password = ''
|
|
||||||
t = {}
|
this.password = ''
|
||||||
ready = false
|
this.confirm_password = ''
|
||||||
|
this.t = {}
|
||||||
|
this.ready = false
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.has_mfa = !!session.get('user.has_mfa')
|
this.has_mfa = !!session.get('user.has_mfa')
|
||||||
|
@ -63,18 +63,21 @@ export default class AuthLoginForm extends Component {
|
|||||||
] }
|
] }
|
||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
|
|
||||||
username = ''
|
constructor() {
|
||||||
password = ''
|
super()
|
||||||
button_text = ''
|
|
||||||
step_two = false
|
|
||||||
btn_disabled = true
|
|
||||||
loading = false
|
|
||||||
error_message = ''
|
|
||||||
other_message = ''
|
|
||||||
allow_back = true
|
|
||||||
auth_user = false
|
|
||||||
|
|
||||||
t = {}
|
this.username = ''
|
||||||
|
this.password = ''
|
||||||
|
this.button_text = ''
|
||||||
|
this.step_two = false
|
||||||
|
this.btn_disabled = true
|
||||||
|
this.loading = false
|
||||||
|
this.error_message = ''
|
||||||
|
this.other_message = ''
|
||||||
|
this.allow_back = true
|
||||||
|
this.auth_user = false
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
watch_username(new_username, old_username) {
|
watch_username(new_username, old_username) {
|
||||||
this.btn_disabled = !new_username
|
this.btn_disabled = !new_username
|
||||||
|
@ -98,19 +98,23 @@ export default class RegistrationFormComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return ['app_name'] }
|
static get props() { return ['app_name'] }
|
||||||
|
|
||||||
loading = false
|
constructor() {
|
||||||
step = 1
|
super()
|
||||||
other_message = ''
|
|
||||||
error_message = ''
|
|
||||||
message = ''
|
|
||||||
btn_disabled = true
|
|
||||||
button_text = ''
|
|
||||||
|
|
||||||
first_name = ''
|
this.loading = false
|
||||||
last_name = ''
|
this.step = 1
|
||||||
username = ''
|
this.other_message = ''
|
||||||
email = ''
|
this.error_message = ''
|
||||||
t = {}
|
this.message = ''
|
||||||
|
this.btn_disabled = true
|
||||||
|
this.button_text = ''
|
||||||
|
|
||||||
|
this.first_name = ''
|
||||||
|
this.last_name = ''
|
||||||
|
this.username = ''
|
||||||
|
this.email = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
// Batch-load translated phrases
|
// Batch-load translated phrases
|
||||||
|
@ -146,20 +146,24 @@ export default class FormComponent extends Component {
|
|||||||
return ['resource', 'form_id', 'initial_mode']
|
return ['resource', 'form_id', 'initial_mode']
|
||||||
}
|
}
|
||||||
|
|
||||||
definition = {}
|
constructor() {
|
||||||
data = {}
|
super()
|
||||||
uuid = ''
|
|
||||||
title = ''
|
|
||||||
error_message = ''
|
|
||||||
other_message = ''
|
|
||||||
|
|
||||||
access_msg = ''
|
this.definition = {}
|
||||||
can_access = false
|
this.data = {}
|
||||||
|
this.uuid = ''
|
||||||
|
this.title = ''
|
||||||
|
this.error_message = ''
|
||||||
|
this.other_message = ''
|
||||||
|
|
||||||
is_ready = false
|
this.access_msg = ''
|
||||||
mode = ''
|
this.can_access = false
|
||||||
id = ''
|
|
||||||
t = {}
|
this.is_ready = false
|
||||||
|
this.mode = ''
|
||||||
|
this.id = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.definition = {}
|
this.definition = {}
|
||||||
|
@ -65,13 +65,17 @@ export default class ListingComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return ['resource'] }
|
static get props() { return ['resource'] }
|
||||||
|
|
||||||
definition = {}
|
constructor() {
|
||||||
data = []
|
super()
|
||||||
resource_class = {}
|
|
||||||
|
|
||||||
access_msg = ''
|
this.definition = {}
|
||||||
can_access = false
|
this.data = []
|
||||||
t = {}
|
this.resource_class = {}
|
||||||
|
|
||||||
|
this.access_msg = ''
|
||||||
|
this.can_access = false
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.t = await T(
|
this.t = await T(
|
||||||
|
@ -232,35 +232,39 @@ export default class AppSetupComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return [] }
|
static get props() { return [] }
|
||||||
|
|
||||||
step = 0
|
constructor() {
|
||||||
btn_disabled = true
|
super()
|
||||||
btn_back = false
|
|
||||||
btn_hidden = false
|
|
||||||
btn_listing = false
|
|
||||||
|
|
||||||
name = ''
|
this.step = 0
|
||||||
identifier = ''
|
this.btn_disabled = true
|
||||||
type = '' // ldap | saml | oauth
|
this.btn_back = false
|
||||||
oauth_redirect_uri = ''
|
this.btn_hidden = false
|
||||||
|
this.btn_listing = false
|
||||||
|
|
||||||
saml_entity_id = ''
|
this.name = ''
|
||||||
saml_acs_url = ''
|
this.identifier = ''
|
||||||
saml_slo_url = ''
|
this.type = '' // ldap | saml | oauth
|
||||||
|
this.oauth_redirect_uri = ''
|
||||||
|
|
||||||
ldap_username = ''
|
this.saml_entity_id = ''
|
||||||
ldap_password = ''
|
this.saml_acs_url = ''
|
||||||
ldap_password_confirm = ''
|
this.saml_slo_url = ''
|
||||||
ldap_config = {}
|
|
||||||
|
|
||||||
error_message = ''
|
this.ldap_username = ''
|
||||||
|
this.ldap_password = ''
|
||||||
|
this.ldap_password_confirm = ''
|
||||||
|
this.ldap_config = {}
|
||||||
|
|
||||||
app = {}
|
this.error_message = ''
|
||||||
oauth_client = {}
|
|
||||||
saml_provider = {}
|
|
||||||
ldap_client = {}
|
|
||||||
|
|
||||||
app_name = ''
|
this.app = {}
|
||||||
host = ''
|
this.oauth_client = {}
|
||||||
|
this.saml_provider = {}
|
||||||
|
this.ldap_client = {}
|
||||||
|
|
||||||
|
this.app_name = ''
|
||||||
|
this.host = ''
|
||||||
|
}
|
||||||
|
|
||||||
make_url(path) {
|
make_url(path) {
|
||||||
return session.url(path)
|
return session.url(path)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Component } from '../../lib/vues6/vues6.js'
|
import { Component } from '../../lib/vues6/vues6.js'
|
||||||
import { event_bus } from '../service/EventBus.service.js'
|
import { event_bus } from '../service/EventBus.service.js'
|
||||||
import { session } from '../service/Session.service.js'
|
import { session } from '../service/Session.service.js'
|
||||||
import { message_service } from '../service/Message.service.js'
|
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
|
||||||
@ -53,10 +52,10 @@ export default class NavBarComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return [] }
|
static get props() { return [] }
|
||||||
|
|
||||||
can = {}
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
this.can = {}
|
||||||
this.toggle_event = event_bus.event('sidebar.toggle')
|
this.toggle_event = event_bus.event('sidebar.toggle')
|
||||||
this.first_name = session.get('user.first_name')
|
this.first_name = session.get('user.first_name')
|
||||||
this.last_name = session.get('user.last_name')
|
this.last_name = session.get('user.last_name')
|
||||||
|
@ -23,72 +23,75 @@ export default class SideBarComponent extends Component {
|
|||||||
static get props() { return ['app_name'] }
|
static get props() { return ['app_name'] }
|
||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
|
|
||||||
actions = []
|
|
||||||
|
|
||||||
possible_actions = [
|
|
||||||
{
|
|
||||||
text: 'Profile',
|
|
||||||
action: 'redirect',
|
|
||||||
next: '/dash/profile',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Users',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'auth/User',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Groups',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'auth/Group',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Applications',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'App',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'IAM Policy',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'iam/Policy',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'LDAP Clients',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'ldap/Client',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'OAuth2 Clients',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'oauth/Client',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'OpenID Connect Clients',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'openid/Client',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'SAML Service Providers',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'saml/Provider',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Settings',
|
|
||||||
action: 'list',
|
|
||||||
type: 'resource',
|
|
||||||
resource: 'Setting',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
this.actions = []
|
||||||
|
|
||||||
|
this.isCollapsed = false
|
||||||
|
|
||||||
|
this.possible_actions = [
|
||||||
|
{
|
||||||
|
text: 'Profile',
|
||||||
|
action: 'redirect',
|
||||||
|
next: '/dash/profile',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Users',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'auth/User',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Groups',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'auth/Group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Applications',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'App',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'IAM Policy',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'iam/Policy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'LDAP Clients',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'ldap/Client',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'OAuth2 Clients',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'oauth/Client',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'OpenID Connect Clients',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'openid/Client',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'SAML Service Providers',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'saml/Provider',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Settings',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'Setting',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
event_bus.event('sidebar.toggle').subscribe(() => {
|
event_bus.event('sidebar.toggle').subscribe(() => {
|
||||||
this.toggle()
|
this.toggle()
|
||||||
})
|
})
|
||||||
@ -120,8 +123,6 @@ export default class SideBarComponent extends Component {
|
|||||||
this.actions = new_actions
|
this.actions = new_actions
|
||||||
}
|
}
|
||||||
|
|
||||||
isCollapsed = false
|
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
this.isCollapsed = !this.isCollapsed
|
this.isCollapsed = !this.isCollapsed
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,12 @@ export default class MessageContainerComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return [] }
|
static get props() { return [] }
|
||||||
|
|
||||||
messages = []
|
constructor() {
|
||||||
modals = []
|
super()
|
||||||
|
|
||||||
|
this.messages = []
|
||||||
|
this.modals = []
|
||||||
|
}
|
||||||
|
|
||||||
vue_on_create() {
|
vue_on_create() {
|
||||||
this.alert_event = event_bus.event('message.alert')
|
this.alert_event = event_bus.event('message.alert')
|
||||||
|
@ -195,31 +195,35 @@ export default class EditProfileComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return ['user_id'] }
|
static get props() { return ['user_id'] }
|
||||||
|
|
||||||
profile_first = ''
|
constructor() {
|
||||||
profile_last = ''
|
super()
|
||||||
profile_email = ''
|
|
||||||
profile_tagline = ''
|
|
||||||
last_reset = ''
|
|
||||||
mfa_enable_date = ''
|
|
||||||
|
|
||||||
has_mfa_recovery = false
|
this.profile_first = ''
|
||||||
mfa_recovery_date = ''
|
this.profile_last = ''
|
||||||
mfa_recovery_codes = 0
|
this.profile_email = ''
|
||||||
|
this.profile_tagline = ''
|
||||||
|
this.last_reset = ''
|
||||||
|
this.mfa_enable_date = ''
|
||||||
|
|
||||||
form_message = 'No changes.'
|
this.has_mfa_recovery = false
|
||||||
|
this.mfa_recovery_date = ''
|
||||||
|
this.mfa_recovery_codes = 0
|
||||||
|
|
||||||
has_mfa = false
|
this.form_message = 'No changes.'
|
||||||
ready = false
|
|
||||||
|
|
||||||
notify_gateway_url = ''
|
this.has_mfa = false
|
||||||
notify_app_key = ''
|
this.ready = false
|
||||||
notify_enabled = false
|
|
||||||
notify_created_on = ''
|
|
||||||
notify_loaded = false
|
|
||||||
|
|
||||||
app_passwords = []
|
this.notify_gateway_url = ''
|
||||||
app_name = ''
|
this.notify_app_key = ''
|
||||||
t = {}
|
this.notify_enabled = false
|
||||||
|
this.notify_created_on = ''
|
||||||
|
this.notify_loaded = false
|
||||||
|
|
||||||
|
this.app_passwords = []
|
||||||
|
this.app_name = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
on_key_up = ($event) => {}
|
on_key_up = ($event) => {}
|
||||||
|
|
||||||
|
@ -72,12 +72,16 @@ export default class AppPasswordFormComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get props() { return [] }
|
static get props() { return [] }
|
||||||
|
|
||||||
name = ''
|
constructor() {
|
||||||
valid = false
|
super()
|
||||||
uuid = ''
|
|
||||||
enable_form = true
|
this.name = ''
|
||||||
display_password = ''
|
this.valid = false
|
||||||
t = {}
|
this.uuid = ''
|
||||||
|
this.enable_form = true
|
||||||
|
this.display_password = ''
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.t = await T(
|
this.t = await T(
|
||||||
|
@ -29,8 +29,12 @@ export default class ProfilePhotoUploaderComponent extends Component {
|
|||||||
static get template() { return template }
|
static get template() { return template }
|
||||||
static get params() { return [] }
|
static get params() { return [] }
|
||||||
|
|
||||||
ready = false
|
constructor() {
|
||||||
t = {}
|
super()
|
||||||
|
|
||||||
|
this.ready = false
|
||||||
|
this.t = {}
|
||||||
|
}
|
||||||
|
|
||||||
async vue_on_create() {
|
async vue_on_create() {
|
||||||
this.t = await T(
|
this.t = await T(
|
||||||
|
@ -2,126 +2,130 @@ import CRUDBase from './CRUDBase.js'
|
|||||||
import { session } from '../service/Session.service.js'
|
import { session } from '../service/Session.service.js'
|
||||||
|
|
||||||
class AppResource extends CRUDBase {
|
class AppResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/applications'
|
constructor() {
|
||||||
required_fields = ['name', 'identifier']
|
super()
|
||||||
permission_base = 'v1:applications'
|
|
||||||
|
|
||||||
item = 'Application'
|
this.endpoint = '/api/v1/applications'
|
||||||
plural = 'Applications'
|
this.required_fields = ['name', 'identifier']
|
||||||
|
this.permission_base = 'v1:applications'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'Application'
|
||||||
display: `
|
this.plural = 'Applications'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
An application is anything that can authenticate users against ${session.get('app.name')}. Applications can have any number of associated LDAP clients, SAML service providers, and OAuth2 clients.
|
An application is anything that can authenticate users against ${session.get('app.name')}. Applications can have any number of associated LDAP clients, SAML service providers, and OAuth2 clients.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Identifier',
|
name: 'Identifier',
|
||||||
field: 'identifier',
|
field: 'identifier',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Description',
|
name: 'Description',
|
||||||
field: 'description',
|
field: 'description',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
text: 'Manual Setup',
|
text: 'Manual Setup',
|
||||||
color: 'outline-success',
|
color: 'outline-success',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'redirect',
|
action: 'redirect',
|
||||||
text: 'Setup Wizard',
|
text: 'Setup Wizard',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
next: '/dash/app/setup',
|
next: '/dash/app/setup',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
icon: 'fa fa-times',
|
icon: 'fa fa-times',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
confirm: true,
|
confirm: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
this.form_definition = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
placeholder: 'Awesome App',
|
placeholder: 'Awesome App',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Identifier',
|
|
||||||
field: 'identifier',
|
|
||||||
placeholder: 'awesome_app',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Description',
|
|
||||||
field: 'description',
|
|
||||||
type: 'textarea',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Associated LDAP Clients',
|
|
||||||
field: 'ldap_client_ids',
|
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'ldap/Client',
|
|
||||||
display: 'name',
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'Identifier',
|
||||||
name: 'Associated OAuth2 Clients',
|
field: 'identifier',
|
||||||
field: 'oauth_client_ids',
|
placeholder: 'awesome_app',
|
||||||
type: 'select.dynamic.multiple',
|
required: true,
|
||||||
options: {
|
type: 'text',
|
||||||
resource: 'oauth/Client',
|
|
||||||
display: 'name',
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'Description',
|
||||||
name: 'Associated OpenID Connect Clients',
|
field: 'description',
|
||||||
field: 'openid_client_ids',
|
type: 'textarea',
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'openid/Client',
|
|
||||||
display: 'client_name',
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'Associated LDAP Clients',
|
||||||
name: 'Associated SAML Service Providers',
|
field: 'ldap_client_ids',
|
||||||
field: 'saml_service_provider_ids',
|
type: 'select.dynamic.multiple',
|
||||||
type: 'select.dynamic.multiple',
|
options: {
|
||||||
options: {
|
resource: 'ldap/Client',
|
||||||
resource: 'saml/Provider',
|
display: 'name',
|
||||||
display: 'name',
|
value: 'id',
|
||||||
value: 'id',
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
],
|
name: 'Associated OAuth2 Clients',
|
||||||
|
field: 'oauth_client_ids',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'oauth/Client',
|
||||||
|
display: 'name',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Associated OpenID Connect Clients',
|
||||||
|
field: 'openid_client_ids',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'openid/Client',
|
||||||
|
display: 'client_name',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Associated SAML Service Providers',
|
||||||
|
field: 'saml_service_provider_ids',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'saml/Provider',
|
||||||
|
display: 'name',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,17 @@ import APIParseError from './APIParseError.js'
|
|||||||
import { session } from '../service/Session.service.js'
|
import { session } from '../service/Session.service.js'
|
||||||
|
|
||||||
export default class CRUDBase {
|
export default class CRUDBase {
|
||||||
endpoint = '/api/v1'
|
constructor() {
|
||||||
required_fields = []
|
this.endpoint = '/api/v1'
|
||||||
permission_base = ''
|
this.required_fields = []
|
||||||
|
this.permission_base = ''
|
||||||
|
|
||||||
listing_definition = {}
|
this.listing_definition = {}
|
||||||
form_definition = {}
|
this.form_definition = {}
|
||||||
|
|
||||||
item = ''
|
this.item = ''
|
||||||
plural = ''
|
this.plural = ''
|
||||||
|
}
|
||||||
|
|
||||||
async can(action) {
|
async can(action) {
|
||||||
return session.check_permissions(`${this.permission_base}:${action}`)
|
return session.check_permissions(`${this.permission_base}:${action}`)
|
||||||
|
@ -2,53 +2,57 @@ import CRUDBase from './CRUDBase.js'
|
|||||||
import { session } from '../service/Session.service.js'
|
import { session } from '../service/Session.service.js'
|
||||||
|
|
||||||
class SettingResource extends CRUDBase {
|
class SettingResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/settings'
|
constructor() {
|
||||||
required_fields = ['key', 'value']
|
super()
|
||||||
permission_base = 'v1:settings'
|
|
||||||
|
|
||||||
item = 'Setting'
|
this.endpoint = '/api/v1/settings'
|
||||||
plural = 'Settings'
|
this.required_fields = ['key', 'value']
|
||||||
|
this.permission_base = 'v1:settings'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'Setting'
|
||||||
display: `
|
this.plural = 'Settings'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
<p>These are advanced settings that allow you to tweak the way ${session.get('app.name')} behaves. Tweak them at your own risk.</p>
|
<p>These are advanced settings that allow you to tweak the way ${session.get('app.name')} behaves. Tweak them at your own risk.</p>
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Setting Key',
|
name: 'Setting Key',
|
||||||
field: 'key',
|
field: 'key',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Value',
|
name: 'Value',
|
||||||
field: 'value',
|
field: 'value',
|
||||||
renderer: (v) => JSON.stringify(v),
|
renderer: (v) => JSON.stringify(v),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
this.form_definition = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Setting Key',
|
name: 'Setting Key',
|
||||||
field: 'key',
|
field: 'key',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
readonly: true,
|
readonly: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Value (JSON)',
|
name: 'Value (JSON)',
|
||||||
field: 'value',
|
field: 'value',
|
||||||
type: 'json',
|
type: 'json',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,74 +2,78 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js'
|
import { session } from '../../service/Session.service.js'
|
||||||
|
|
||||||
class GroupResource extends CRUDBase {
|
class GroupResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/auth/groups'
|
constructor() {
|
||||||
required_fields = ['name']
|
super()
|
||||||
permission_base = 'v1:auth:groups'
|
|
||||||
|
|
||||||
item = 'Group'
|
this.endpoint = '/api/v1/auth/groups'
|
||||||
plural = 'Groups'
|
this.required_fields = ['name']
|
||||||
|
this.permission_base = 'v1:auth:groups'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'Group'
|
||||||
display: `
|
this.plural = 'Groups'
|
||||||
In ${session.get('app.name')}, groups are simply a tool for organizing users and assigning permissions and access in bulk. After creating and assigning users to a group, you can manage permissions for that group, and its policies will be applied to all users in that group.
|
|
||||||
`,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'Name',
|
|
||||||
field: 'name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '# of Users',
|
|
||||||
field: 'user_ids',
|
|
||||||
renderer: (user_ids) => Array.isArray(user_ids) ? user_ids.length : 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'main',
|
|
||||||
action: 'insert',
|
|
||||||
text: 'Create New',
|
|
||||||
color: 'success',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'update',
|
|
||||||
icon: 'fa fa-edit',
|
|
||||||
color: 'primary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'delete',
|
|
||||||
icon: 'fa fa-times',
|
|
||||||
color: 'danger',
|
|
||||||
confirm: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
form_definition = {
|
this.listing_definition = {
|
||||||
fields: [
|
display: `
|
||||||
{
|
In ${session.get('app.name')}, groups are simply a tool for organizing users and assigning permissions and access in bulk. After creating and assigning users to a group, you can manage permissions for that group, and its policies will be applied to all users in that group.
|
||||||
name: 'Name',
|
`,
|
||||||
field: 'name',
|
columns: [
|
||||||
placeholder: 'Some Cool Users',
|
{
|
||||||
required: true,
|
name: 'Name',
|
||||||
type: 'text',
|
field: 'name',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Users',
|
|
||||||
field: 'user_ids',
|
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/User',
|
|
||||||
display: (user) => `${user.last_name}, ${user.first_name} (${user.uid})`,
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
],
|
name: '# of Users',
|
||||||
|
field: 'user_ids',
|
||||||
|
renderer: (user_ids) => Array.isArray(user_ids) ? user_ids.length : 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'main',
|
||||||
|
action: 'insert',
|
||||||
|
text: 'Create New',
|
||||||
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Name',
|
||||||
|
field: 'name',
|
||||||
|
placeholder: 'Some Cool Users',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Users',
|
||||||
|
field: 'user_ids',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'auth/User',
|
||||||
|
display: (user) => `${user.last_name}, ${user.first_name} (${user.uid})`,
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
import CRUDBase from '../CRUDBase.js'
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
class RoleResource extends CRUDBase {
|
class RoleResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/auth/roles'
|
|
||||||
required_fields = ['role', 'permissions']
|
|
||||||
permission_base = 'v1:auth:roles'
|
|
||||||
|
|
||||||
item = 'Role'
|
constructor() {
|
||||||
plural = 'Roles'
|
super()
|
||||||
|
|
||||||
|
this.endpoint = '/api/v1/auth/roles'
|
||||||
|
this.required_fields = ['role', 'permissions']
|
||||||
|
this.permission_base = 'v1:auth:roles'
|
||||||
|
|
||||||
|
this.item = 'Role'
|
||||||
|
this.plural = 'Roles'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auth_role = new RoleResource()
|
const auth_role = new RoleResource()
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import CRUDBase from '../CRUDBase.js'
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
class TrapResource extends CRUDBase {
|
class TrapResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/auth/traps'
|
constructor() {
|
||||||
required_fields = ['name', 'trap', 'redirect_to']
|
super()
|
||||||
permission_base = 'v1:auth:traps'
|
|
||||||
|
|
||||||
item = 'Trap'
|
this.endpoint = '/api/v1/auth/traps'
|
||||||
plural = 'Traps'
|
this.required_fields = ['name', 'trap', 'redirect_to']
|
||||||
|
this.permission_base = 'v1:auth:traps'
|
||||||
|
|
||||||
|
this.item = 'Trap'
|
||||||
|
this.plural = 'Traps'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auth_trap = new TrapResource()
|
const auth_trap = new TrapResource()
|
||||||
|
@ -2,114 +2,118 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js'
|
import { session } from '../../service/Session.service.js'
|
||||||
|
|
||||||
class UserResource extends CRUDBase {
|
class UserResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/auth/users'
|
constructor() {
|
||||||
required_fields = ['uid', 'first_name', 'last_name', 'email']
|
super()
|
||||||
permission_base = 'v1:auth:users'
|
|
||||||
|
|
||||||
item = 'User'
|
this.endpoint = '/api/v1/auth/users'
|
||||||
plural = 'Users'
|
this.required_fields = ['uid', 'first_name', 'last_name', 'email']
|
||||||
|
this.permission_base = 'v1:auth:users'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'User'
|
||||||
display: `
|
this.plural = 'Users'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
Users can be assigned permissions and, if granted, can manage their ${session.get('app.name')} accounts from the Profile page, as well as login to the external applications they've been given access to.
|
Users can be assigned permissions and, if granted, can manage their ${session.get('app.name')} accounts from the Profile page, as well as login to the external applications they've been given access to.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'UID',
|
name: 'UID',
|
||||||
field: 'uid',
|
field: 'uid',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Last Name',
|
|
||||||
field: 'last_name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'First Name',
|
|
||||||
field: 'first_name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'E-Mail',
|
|
||||||
field: 'email',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'main',
|
|
||||||
action: 'insert',
|
|
||||||
text: 'Create New',
|
|
||||||
color: 'success',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'update',
|
|
||||||
icon: 'fa fa-edit',
|
|
||||||
color: 'primary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'delete',
|
|
||||||
icon: 'fa fa-times',
|
|
||||||
color: 'danger',
|
|
||||||
confirm: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
form_definition = {
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'First Name',
|
|
||||||
field: 'first_name',
|
|
||||||
placeholder: 'John',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Last Name',
|
|
||||||
field: 'last_name',
|
|
||||||
placeholder: 'Doe',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Username',
|
|
||||||
field: 'uid',
|
|
||||||
placeholder: 'john.doe',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'E-Mail',
|
|
||||||
field: 'email',
|
|
||||||
placeholder: 'john@contoso.com',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Tagline',
|
|
||||||
field: 'tagline',
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Password',
|
|
||||||
field: 'password',
|
|
||||||
type: 'password',
|
|
||||||
placeholder: 'Password',
|
|
||||||
required: ['insert'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Trap',
|
|
||||||
field: 'trap',
|
|
||||||
type: 'select.dynamic',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/Trap',
|
|
||||||
display: 'name',
|
|
||||||
value: 'trap',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
],
|
name: 'Last Name',
|
||||||
|
field: 'last_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'First Name',
|
||||||
|
field: 'first_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'E-Mail',
|
||||||
|
field: 'email',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'main',
|
||||||
|
action: 'insert',
|
||||||
|
text: 'Create New',
|
||||||
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'First Name',
|
||||||
|
field: 'first_name',
|
||||||
|
placeholder: 'John',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Last Name',
|
||||||
|
field: 'last_name',
|
||||||
|
placeholder: 'Doe',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Username',
|
||||||
|
field: 'uid',
|
||||||
|
placeholder: 'john.doe',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'E-Mail',
|
||||||
|
field: 'email',
|
||||||
|
placeholder: 'john@contoso.com',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Tagline',
|
||||||
|
field: 'tagline',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Password',
|
||||||
|
field: 'password',
|
||||||
|
type: 'password',
|
||||||
|
placeholder: 'Password',
|
||||||
|
required: ['insert'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Trap',
|
||||||
|
field: 'trap',
|
||||||
|
type: 'select.dynamic',
|
||||||
|
options: {
|
||||||
|
resource: 'auth/Trap',
|
||||||
|
display: 'name',
|
||||||
|
value: 'trap',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,18 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js'
|
import { session } from '../../service/Session.service.js'
|
||||||
|
|
||||||
class PolicyResource extends CRUDBase {
|
class PolicyResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/iam/policy'
|
constructor() {
|
||||||
required_fields = ['entity_id', 'entity_type', 'target_id', 'target_type', 'access_type']
|
super()
|
||||||
permission_base = 'v1:iam:policy'
|
|
||||||
|
|
||||||
item = 'IAM Policy'
|
this.endpoint = '/api/v1/iam/policy'
|
||||||
plural = 'IAM Policies'
|
this.required_fields = ['entity_id', 'entity_type', 'target_id', 'target_type', 'access_type']
|
||||||
|
this.permission_base = 'v1:iam:policy'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'IAM Policy'
|
||||||
display: `
|
this.plural = 'IAM Policies'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
Identity & Access Management (IAM) policies give you fine grained control over which ${session.get('app.name')} users and groups are allowed to access which applications.
|
Identity & Access Management (IAM) policies give you fine grained control over which ${session.get('app.name')} users and groups are allowed to access which applications.
|
||||||
<br><br>
|
<br><br>
|
||||||
An IAM policy has three parts. First, is the subject. The subject is who the policy applies to and is either a user or a group. The second part is the access type. This is either an allowance or a denial. That is, the policy either grants a subject access to a resource, or explicitly denies them access. The final part of the policy is the target. This is the application that the subject is being granted or denied access to.
|
An IAM policy has three parts. First, is the subject. The subject is who the policy applies to and is either a user or a group. The second part is the access type. This is either an allowance or a denial. That is, the policy either grants a subject access to a resource, or explicitly denies them access. The final part of the policy is the target. This is the application that the subject is being granted or denied access to.
|
||||||
@ -24,136 +27,137 @@ class PolicyResource extends CRUDBase {
|
|||||||
</ol>
|
</ol>
|
||||||
This means, for example, that if a user's group is allowed access, but a user is denied access, the user will be denied access. Likewise, if there are two policies for a subject, one granting them access and one denying them access, the denial will take precedence.
|
This means, for example, that if a user's group is allowed access, but a user is denied access, the user will be denied access. Likewise, if there are two policies for a subject, one granting them access and one denying them access, the denial will take precedence.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Subject',
|
name: 'Subject',
|
||||||
field: 'entity_display',
|
field: 'entity_display',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Access Type',
|
name: 'Access Type',
|
||||||
field: 'access_type',
|
field: 'access_type',
|
||||||
renderer: access_type => access_type === 'deny' ? '...is denied access to...' : '...is granted access to...',
|
renderer: access_type => access_type === 'deny' ? '...is denied access to...' : '...is granted access to...',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Target',
|
name: 'Target',
|
||||||
field: 'target_display',
|
field: 'target_display',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
text: 'Create New',
|
text: 'Create New',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
icon: 'fa fa-times',
|
icon: 'fa fa-times',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
confirm: true,
|
confirm: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
this.form_definition = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Subject Type',
|
name: 'Subject Type',
|
||||||
field: 'entity_type',
|
field: 'entity_type',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'select',
|
type: 'select',
|
||||||
options: [
|
options: [
|
||||||
{ display: 'User', value: 'user' },
|
{display: 'User', value: 'user'},
|
||||||
{ display: 'Group', value: 'group' },
|
{display: 'Group', value: 'group'},
|
||||||
],
|
],
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Subject',
|
|
||||||
field: 'entity_id',
|
|
||||||
required: true,
|
|
||||||
type: 'select.dynamic',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/User',
|
|
||||||
display: user => `User: ${user.last_name}, ${user.first_name} (${user.uid})`,
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
if: (form_data) => form_data.entity_type === 'user',
|
{
|
||||||
},
|
name: 'Subject',
|
||||||
{
|
field: 'entity_id',
|
||||||
name: 'Subject',
|
required: true,
|
||||||
field: 'entity_id',
|
type: 'select.dynamic',
|
||||||
required: true,
|
options: {
|
||||||
type: 'select.dynamic',
|
resource: 'auth/User',
|
||||||
options: {
|
display: user => `User: ${user.last_name}, ${user.first_name} (${user.uid})`,
|
||||||
resource: 'auth/Group',
|
value: 'id',
|
||||||
display: group => `Group: ${group.name} (${group.user_ids.length} users)`,
|
},
|
||||||
value: 'id',
|
if: (form_data) => form_data.entity_type === 'user',
|
||||||
},
|
},
|
||||||
if: (form_data) => form_data.entity_type === 'group',
|
{
|
||||||
},
|
name: 'Subject',
|
||||||
{
|
field: 'entity_id',
|
||||||
name: 'Access Type',
|
required: true,
|
||||||
field: 'access_type',
|
type: 'select.dynamic',
|
||||||
required: true,
|
options: {
|
||||||
type: 'select',
|
resource: 'auth/Group',
|
||||||
options: [
|
display: group => `Group: ${group.name} (${group.user_ids.length} users)`,
|
||||||
{ display: '...is granted access to...', value: 'allow' },
|
value: 'id',
|
||||||
{ display: '...is denied access to...', value: 'deny' },
|
},
|
||||||
],
|
if: (form_data) => form_data.entity_type === 'group',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Target Type',
|
|
||||||
field: 'target_type',
|
|
||||||
required: true,
|
|
||||||
type: 'select',
|
|
||||||
options: [
|
|
||||||
{ display: 'Application', value: 'application' },
|
|
||||||
{ display: 'API Scope', value: 'api_scope' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Target',
|
|
||||||
field: 'target_id',
|
|
||||||
required: true,
|
|
||||||
type: 'select.dynamic',
|
|
||||||
options: {
|
|
||||||
resource: 'App',
|
|
||||||
display: 'name',
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
if: (form_data) => form_data.target_type === 'application'
|
{
|
||||||
},
|
name: 'Access Type',
|
||||||
{
|
field: 'access_type',
|
||||||
name: 'Target',
|
required: true,
|
||||||
field: 'target_id',
|
type: 'select',
|
||||||
required: true,
|
options: [
|
||||||
type: 'select.dynamic',
|
{display: '...is granted access to...', value: 'allow'},
|
||||||
options: {
|
{display: '...is denied access to...', value: 'deny'},
|
||||||
resource: 'reflect/Scope',
|
],
|
||||||
display: 'scope',
|
|
||||||
value: 'scope',
|
|
||||||
},
|
},
|
||||||
if: (form_data) => form_data.target_type === 'api_scope'
|
{
|
||||||
},
|
name: 'Target Type',
|
||||||
],
|
field: 'target_type',
|
||||||
/*handlers: {
|
required: true,
|
||||||
insert: {
|
type: 'select',
|
||||||
action: 'back',
|
options: [
|
||||||
},
|
{display: 'Application', value: 'application'},
|
||||||
update: {
|
{display: 'API Scope', value: 'api_scope'},
|
||||||
action: 'back',
|
],
|
||||||
},
|
},
|
||||||
},*/
|
{
|
||||||
|
name: 'Target',
|
||||||
|
field: 'target_id',
|
||||||
|
required: true,
|
||||||
|
type: 'select.dynamic',
|
||||||
|
options: {
|
||||||
|
resource: 'App',
|
||||||
|
display: 'name',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
if: (form_data) => form_data.target_type === 'application'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Target',
|
||||||
|
field: 'target_id',
|
||||||
|
required: true,
|
||||||
|
type: 'select.dynamic',
|
||||||
|
options: {
|
||||||
|
resource: 'reflect/Scope',
|
||||||
|
display: 'scope',
|
||||||
|
value: 'scope',
|
||||||
|
},
|
||||||
|
if: (form_data) => form_data.target_type === 'api_scope'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
/*handlers: {
|
||||||
|
insert: {
|
||||||
|
action: 'back',
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
action: 'back',
|
||||||
|
},
|
||||||
|
},*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,83 +2,88 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js'
|
import { session } from '../../service/Session.service.js'
|
||||||
|
|
||||||
class ClientResource extends CRUDBase {
|
class ClientResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/ldap/clients'
|
constructor() {
|
||||||
required_fields = ['name', 'uid', 'password']
|
super()
|
||||||
permission_base = 'v1:ldap:clients'
|
|
||||||
|
|
||||||
item = 'LDAP Client'
|
this.endpoint = '/api/v1/ldap/clients'
|
||||||
plural = 'LDAP Clients'
|
this.required_fields = ['name', 'uid', 'password']
|
||||||
|
this.permission_base = 'v1:ldap:clients'
|
||||||
|
|
||||||
async server_config() {
|
this.item = 'LDAP Client'
|
||||||
const results = await axios.get('/api/v1/ldap/config')
|
this.plural = 'LDAP Clients'
|
||||||
if ( results && results.data && results.data.data ) return results.data.data
|
|
||||||
}
|
|
||||||
|
|
||||||
listing_definition = {
|
|
||||||
display: `
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
LDAP Clients are special user accounts that external applications can use to bind to ${session.get('app.name')}'s built-in LDAP server to allow these applications to authenticate users.
|
LDAP Clients are special user accounts that external applications can use to bind to ${session.get('app.name')}'s built-in LDAP server to allow these applications to authenticate users.
|
||||||
<br><br>
|
<br><br>
|
||||||
These special accounts are permitted to bind to the LDAP server, but are not allowed to sign-in to ${session.get('app.name')}.
|
These special accounts are permitted to bind to the LDAP server, but are not allowed to sign-in to ${session.get('app.name')}.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Client Name',
|
name: 'Client Name',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'User ID',
|
name: 'User ID',
|
||||||
field: 'uid',
|
field: 'uid',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
text: 'Create New',
|
text: 'Create New',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
icon: 'fa fa-times',
|
icon: 'fa fa-times',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
confirm: true,
|
confirm: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Provider Name',
|
||||||
|
field: 'name',
|
||||||
|
placeholder: 'Awesome External App',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'User ID',
|
||||||
|
field: 'uid',
|
||||||
|
placeholder: 'some_username',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Password',
|
||||||
|
field: 'password',
|
||||||
|
required: ['insert'],
|
||||||
|
type: 'password',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
async server_config() {
|
||||||
fields: [
|
const results = await axios.get('/api/v1/ldap/config')
|
||||||
{
|
if (results && results.data && results.data.data) return results.data.data
|
||||||
name: 'Provider Name',
|
|
||||||
field: 'name',
|
|
||||||
placeholder: 'Awesome External App',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'User ID',
|
|
||||||
field: 'uid',
|
|
||||||
placeholder: 'some_username',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Password',
|
|
||||||
field: 'password',
|
|
||||||
required: ['insert'],
|
|
||||||
type: 'password',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,97 +1,101 @@
|
|||||||
import CRUDBase from '../CRUDBase.js'
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
class GroupResource extends CRUDBase {
|
class GroupResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/ldap/groups'
|
constructor() {
|
||||||
required_fields = ['name', 'role']
|
super()
|
||||||
permission_base = 'v1:ldap:groups'
|
|
||||||
|
|
||||||
item = 'LDAP Group'
|
this.endpoint = '/api/v1/ldap/groups'
|
||||||
plural = 'LDAP Groups'
|
this.required_fields = ['name', 'role']
|
||||||
|
this.permission_base = 'v1:ldap:groups'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'LDAP Group'
|
||||||
columns: [
|
this.plural = 'LDAP Groups'
|
||||||
{
|
|
||||||
name: 'Group Name',
|
|
||||||
field: 'name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Role',
|
|
||||||
field: 'role',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '# of Users',
|
|
||||||
field: 'user_ids',
|
|
||||||
renderer: (user_ids) => Array.isArray(user_ids) ? user_ids.length : 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'main',
|
|
||||||
action: 'insert',
|
|
||||||
text: 'Create New',
|
|
||||||
color: 'success',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'update',
|
|
||||||
icon: 'fa fa-edit',
|
|
||||||
color: 'primary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'delete',
|
|
||||||
icon: 'fa fa-times',
|
|
||||||
color: 'danger',
|
|
||||||
confirm: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
form_definition = {
|
this.listing_definition = {
|
||||||
// back_action: {
|
columns: [
|
||||||
// text: 'Back',
|
{
|
||||||
// action: 'back',
|
name: 'Group Name',
|
||||||
// },
|
field: 'name',
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'Group Name',
|
|
||||||
field: 'name',
|
|
||||||
placeholder: 'External App Users',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Role',
|
|
||||||
field: 'role',
|
|
||||||
placeholder: 'external_app',
|
|
||||||
required: true,
|
|
||||||
type: 'select.dynamic',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/Role',
|
|
||||||
display: 'role',
|
|
||||||
value: 'role',
|
|
||||||
},
|
},
|
||||||
// options: [
|
{
|
||||||
// { value: 1, display: 'One' },
|
name: 'Role',
|
||||||
// { value: 2, display: 'Two' },
|
field: 'role',
|
||||||
// { value: 3, display: 'Three' },
|
|
||||||
// ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Users',
|
|
||||||
field: 'user_ids',
|
|
||||||
placeholder: 'John Doe',
|
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/User',
|
|
||||||
display: (user) => `${user.last_name}, ${user.first_name} (${user.uid})`,
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
],
|
name: '# of Users',
|
||||||
|
field: 'user_ids',
|
||||||
|
renderer: (user_ids) => Array.isArray(user_ids) ? user_ids.length : 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'main',
|
||||||
|
action: 'insert',
|
||||||
|
text: 'Create New',
|
||||||
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
// back_action: {
|
||||||
|
// text: 'Back',
|
||||||
|
// action: 'back',
|
||||||
|
// },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Group Name',
|
||||||
|
field: 'name',
|
||||||
|
placeholder: 'External App Users',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Role',
|
||||||
|
field: 'role',
|
||||||
|
placeholder: 'external_app',
|
||||||
|
required: true,
|
||||||
|
type: 'select.dynamic',
|
||||||
|
options: {
|
||||||
|
resource: 'auth/Role',
|
||||||
|
display: 'role',
|
||||||
|
value: 'role',
|
||||||
|
},
|
||||||
|
// options: [
|
||||||
|
// { value: 1, display: 'One' },
|
||||||
|
// { value: 2, display: 'Two' },
|
||||||
|
// { value: 3, display: 'Three' },
|
||||||
|
// ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Users',
|
||||||
|
field: 'user_ids',
|
||||||
|
placeholder: 'John Doe',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'auth/User',
|
||||||
|
display: (user) => `${user.last_name}, ${user.first_name} (${user.uid})`,
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,104 +2,108 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js';
|
import { session } from '../../service/Session.service.js';
|
||||||
|
|
||||||
class ClientResource extends CRUDBase {
|
class ClientResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/oauth/clients'
|
constructor() {
|
||||||
required_fields = ['name', 'redirect_url', 'api_scopes']
|
super()
|
||||||
permission_base = 'v1:oauth:clients'
|
|
||||||
|
|
||||||
item = 'OAuth2 Client'
|
this.endpoint = '/api/v1/oauth/clients'
|
||||||
plural = 'OAuth2 Clients'
|
this.required_fields = ['name', 'redirect_url', 'api_scopes']
|
||||||
|
this.permission_base = 'v1:oauth:clients'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'OAuth2 Client'
|
||||||
display: `
|
this.plural = 'OAuth2 Clients'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
OAuth2 clients are applications that support authentication over the OAuth2 protocol. This allows you to add a "Sign-In with XXX" button for ${session.get('app.name')} to the application in question. To do this, you need to create an OAuth2 client for that application, and provide the name, redirect URL, and API scopes.
|
OAuth2 clients are applications that support authentication over the OAuth2 protocol. This allows you to add a "Sign-In with XXX" button for ${session.get('app.name')} to the application in question. To do this, you need to create an OAuth2 client for that application, and provide the name, redirect URL, and API scopes.
|
||||||
<br><br>
|
<br><br>
|
||||||
You must select the API scopes to grant this OAuth2 client. This defines what ${session.get('app.name')} endpoints the application is allowed to access. For most applications, granting the <code>v1:api:users:get</code> and <code>v1:api:groups:get</code> API scopes should be sufficient.
|
You must select the API scopes to grant this OAuth2 client. This defines what ${session.get('app.name')} endpoints the application is allowed to access. For most applications, granting the <code>v1:api:users:get</code> and <code>v1:api:groups:get</code> API scopes should be sufficient.
|
||||||
<br><br>
|
<br><br>
|
||||||
This method can also be used to access the API for other purposes. Hence, the expansive API scopes. ${session.get('app.name')} uses Flitter-Auth's built-in OAuth2 server under the hood, so you can find details on how to configure the OAuth2 clients <a href="https://flitter.garrettmills.dev/tutorial-flitter-auth-oauth2-server.html" target="_blank">here.</a>
|
This method can also be used to access the API for other purposes. Hence, the expansive API scopes. ${session.get('app.name')} uses Flitter-Auth's built-in OAuth2 server under the hood, so you can find details on how to configure the OAuth2 clients <a href="https://flitter.garrettmills.dev/tutorial-flitter-auth-oauth2-server.html" target="_blank">here.</a>
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Client Name',
|
name: 'Client Name',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '# of Scopes',
|
|
||||||
field: 'api_scopes',
|
|
||||||
renderer: (api_scopes) => api_scopes.length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Redirect URL',
|
|
||||||
field: 'redirect_url',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'main',
|
|
||||||
action: 'insert',
|
|
||||||
text: 'Create New',
|
|
||||||
color: 'success',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'update',
|
|
||||||
icon: 'fa fa-edit',
|
|
||||||
color: 'primary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'delete',
|
|
||||||
icon: 'fa fa-times',
|
|
||||||
color: 'danger',
|
|
||||||
confirm: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
form_definition = {
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'Client Name',
|
|
||||||
field: 'name',
|
|
||||||
placeholder: 'Awesome External App',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Redirect URL',
|
|
||||||
field: 'redirect_url',
|
|
||||||
placeholder: 'https://awesome.app/oauth2/callback',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'API Scopes',
|
|
||||||
field: 'api_scopes',
|
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'reflect/Scope',
|
|
||||||
display: 'scope',
|
|
||||||
value: 'scope',
|
|
||||||
},
|
},
|
||||||
required: true,
|
{
|
||||||
},
|
name: '# of Scopes',
|
||||||
{
|
field: 'api_scopes',
|
||||||
name: 'Client ID',
|
renderer: (api_scopes) => api_scopes.length,
|
||||||
field: 'uuid',
|
},
|
||||||
type: 'text',
|
{
|
||||||
readonly: true,
|
name: 'Redirect URL',
|
||||||
hidden: ['insert'],
|
field: 'redirect_url',
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
name: 'Client Secret',
|
actions: [
|
||||||
field: 'secret',
|
{
|
||||||
type: 'text',
|
type: 'resource',
|
||||||
readonly: true,
|
position: 'main',
|
||||||
hidden: ['insert'],
|
action: 'insert',
|
||||||
},
|
text: 'Create New',
|
||||||
],
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Client Name',
|
||||||
|
field: 'name',
|
||||||
|
placeholder: 'Awesome External App',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Redirect URL',
|
||||||
|
field: 'redirect_url',
|
||||||
|
placeholder: 'https://awesome.app/oauth2/callback',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'API Scopes',
|
||||||
|
field: 'api_scopes',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'reflect/Scope',
|
||||||
|
display: 'scope',
|
||||||
|
value: 'scope',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Client ID',
|
||||||
|
field: 'uuid',
|
||||||
|
type: 'text',
|
||||||
|
readonly: true,
|
||||||
|
hidden: ['insert'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Client Secret',
|
||||||
|
field: 'secret',
|
||||||
|
type: 'text',
|
||||||
|
readonly: true,
|
||||||
|
hidden: ['insert'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,94 +2,98 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js'
|
import { session } from '../../service/Session.service.js'
|
||||||
|
|
||||||
class ClientResource extends CRUDBase {
|
class ClientResource extends CRUDBase {
|
||||||
endpoint = '/openid/clients'
|
constructor() {
|
||||||
required_fields = ['client_name', 'grant_types', 'redirect_uri']
|
super()
|
||||||
permission_base = 'v1:openid:clients'
|
|
||||||
|
|
||||||
item = 'OpenID Connect Client'
|
this.endpoint = '/openid/clients'
|
||||||
plural = 'OpenID Connect Clients'
|
this.required_fields = ['client_name', 'grant_types', 'redirect_uri']
|
||||||
|
this.permission_base = 'v1:openid:clients'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'OpenID Connect Client'
|
||||||
display: `
|
this.plural = 'OpenID Connect Clients'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
OpenID Connect clients are applications that support authentication over the OpenID Connect protocol. This allows you to add a "Sign-In with XXX" button for ${session.get('app.name')} to the application in question. To do this, the application need only comply with the OpenID standards.
|
OpenID Connect clients are applications that support authentication over the OpenID Connect protocol. This allows you to add a "Sign-In with XXX" button for ${session.get('app.name')} to the application in question. To do this, the application need only comply with the OpenID standards.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Client Name',
|
name: 'Client Name',
|
||||||
field: 'client_name',
|
field: 'client_name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Redirect URI',
|
name: 'Redirect URI',
|
||||||
field: 'redirect_uri',
|
field: 'redirect_uri',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
text: 'Create New',
|
text: 'Create New',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
icon: 'fa fa-times',
|
icon: 'fa fa-times',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
confirm: true,
|
confirm: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
this.form_definition = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Client Name',
|
name: 'Client Name',
|
||||||
field: 'client_name',
|
field: 'client_name',
|
||||||
placeholder: 'Awesome External App',
|
placeholder: 'Awesome External App',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Redirect URI',
|
name: 'Redirect URI',
|
||||||
field: 'redirect_uri',
|
field: 'redirect_uri',
|
||||||
placeholder: 'https://awesome.app/oauth2/callback',
|
placeholder: 'https://awesome.app/oauth2/callback',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Grant Types',
|
name: 'Grant Types',
|
||||||
field: 'grant_types',
|
field: 'grant_types',
|
||||||
type: 'select.multiple',
|
type: 'select.multiple',
|
||||||
options: [
|
options: [
|
||||||
{ display: 'Refresh Token', value: 'refresh_token' },
|
{display: 'Refresh Token', value: 'refresh_token'},
|
||||||
{ display: 'Authorization Code', value: 'authorization_code' },
|
{display: 'Authorization Code', value: 'authorization_code'},
|
||||||
],
|
],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Client ID',
|
name: 'Client ID',
|
||||||
field: 'client_id',
|
field: 'client_id',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
readonly: true,
|
readonly: true,
|
||||||
hidden: ['insert'],
|
hidden: ['insert'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Client Secret',
|
name: 'Client Secret',
|
||||||
field: 'client_secret',
|
field: 'client_secret',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
readonly: true,
|
readonly: true,
|
||||||
hidden: ['insert'],
|
hidden: ['insert'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import CRUDBase from '../CRUDBase.js'
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
class ScopeResource extends CRUDBase {
|
class ScopeResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/reflect/scopes'
|
constructor() {
|
||||||
required_fields = ['scope']
|
super()
|
||||||
permission_base = 'v1:reflect:scopes'
|
|
||||||
|
|
||||||
item = 'API Scope'
|
this.endpoint = '/api/v1/reflect/scopes'
|
||||||
plural = 'API Scopes'
|
this.required_fields = ['scope']
|
||||||
|
this.permission_base = 'v1:reflect:scopes'
|
||||||
|
|
||||||
|
this.item = 'API Scope'
|
||||||
|
this.plural = 'API Scopes'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reflect_scope = new ScopeResource()
|
const reflect_scope = new ScopeResource()
|
||||||
|
@ -1,87 +1,90 @@
|
|||||||
import CRUDBase from '../CRUDBase.js'
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
class TokenResource extends CRUDBase {
|
class TokenResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/reflect/tokens'
|
constructor() {
|
||||||
required_fields = ['client_id']
|
super()
|
||||||
permission_base = 'v1:reflect:tokens'
|
this.endpoint = '/api/v1/reflect/tokens'
|
||||||
|
this.required_fields = ['client_id']
|
||||||
|
this.permission_base = 'v1:reflect:tokens'
|
||||||
|
|
||||||
item = 'API Token'
|
this.item = 'API Token'
|
||||||
plural = 'API Tokens'
|
this.plural = 'API Tokens'
|
||||||
|
|
||||||
listing_definition = {
|
this.listing_definition = {
|
||||||
display: `
|
display: `
|
||||||
This allows you to create bearer tokens manually to allow for easier testing of the API. Notably, this is meant as a measure for testing and development, not for long term use.
|
This allows you to create bearer tokens manually to allow for easier testing of the API. Notably, this is meant as a measure for testing and development, not for long term use.
|
||||||
<br><br>
|
<br><br>
|
||||||
If you have an application that needs to regularly interact with the API, set it up as an <a href="/dash/c/listing/oauth/Client">OAuth2 Client</a>. Manually-created tokens expire 7 days after their creation.
|
If you have an application that needs to regularly interact with the API, set it up as an <a href="/dash/c/listing/oauth/Client">OAuth2 Client</a>. Manually-created tokens expire 7 days after their creation.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Token',
|
name: 'Token',
|
||||||
field: 'token',
|
field: 'token',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Client',
|
|
||||||
field: 'client_display',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Expires',
|
|
||||||
field: 'expires',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'main',
|
|
||||||
action: 'insert',
|
|
||||||
text: 'Create New',
|
|
||||||
color: 'success',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'update',
|
|
||||||
icon: 'fa fa-edit',
|
|
||||||
color: 'primary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'row',
|
|
||||||
action: 'delete',
|
|
||||||
icon: 'fa fa-times',
|
|
||||||
color: 'danger',
|
|
||||||
confirm: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
form_definition = {
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'Client',
|
|
||||||
field: 'client_id',
|
|
||||||
required: true,
|
|
||||||
type: 'select.dynamic',
|
|
||||||
options: {
|
|
||||||
resource: 'oauth/Client',
|
|
||||||
display: 'name',
|
|
||||||
value: 'uuid',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'Client',
|
||||||
name: 'Bearer Token',
|
field: 'client_display',
|
||||||
field: 'token',
|
},
|
||||||
type: 'text',
|
{
|
||||||
readonly: true,
|
name: 'Expires',
|
||||||
hidden: ['insert'],
|
field: 'expires',
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
name: 'Expires',
|
actions: [
|
||||||
field: 'expires',
|
{
|
||||||
type: 'text',
|
type: 'resource',
|
||||||
readonly: true,
|
position: 'main',
|
||||||
hidden: ['insert'],
|
action: 'insert',
|
||||||
},
|
text: 'Create New',
|
||||||
],
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Client',
|
||||||
|
field: 'client_id',
|
||||||
|
required: true,
|
||||||
|
type: 'select.dynamic',
|
||||||
|
options: {
|
||||||
|
resource: 'oauth/Client',
|
||||||
|
display: 'name',
|
||||||
|
value: 'uuid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Bearer Token',
|
||||||
|
field: 'token',
|
||||||
|
type: 'text',
|
||||||
|
readonly: true,
|
||||||
|
hidden: ['insert'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Expires',
|
||||||
|
field: 'expires',
|
||||||
|
type: 'text',
|
||||||
|
readonly: true,
|
||||||
|
hidden: ['insert'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,92 +2,96 @@ import CRUDBase from '../CRUDBase.js'
|
|||||||
import { session } from '../../service/Session.service.js'
|
import { session } from '../../service/Session.service.js'
|
||||||
|
|
||||||
class ProviderResource extends CRUDBase {
|
class ProviderResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/saml/providers'
|
constructor() {
|
||||||
required_fields = ['name', 'acs_url', 'entity_id']
|
super()
|
||||||
permission_base = 'v1:saml:providers'
|
|
||||||
|
|
||||||
item = 'SAML Service Provider'
|
this.endpoint = '/api/v1/saml/providers'
|
||||||
plural = 'SAML Service Providers'
|
this.required_fields = ['name', 'acs_url', 'entity_id']
|
||||||
|
this.permission_base = 'v1:saml:providers'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'SAML Service Provider'
|
||||||
display: `SAML Service Providers are applications that support external authentication to a SAML Identity Provider. In this case, ${session.get('app.name')} is the identity provider, so these external applications can authenticate against it.
|
this.plural = 'SAML Service Providers'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `SAML Service Providers are applications that support external authentication to a SAML Identity Provider. In this case, ${session.get('app.name')} is the identity provider, so these external applications can authenticate against it.
|
||||||
<br><br>
|
<br><br>
|
||||||
To do this, you need to know the SAML service provider's entity ID, assertion consumer service URL, and single-logout URL (if supported).`,
|
To do this, you need to know the SAML service provider's entity ID, assertion consumer service URL, and single-logout URL (if supported).`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Provider Name',
|
name: 'Provider Name',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Entity ID',
|
name: 'Entity ID',
|
||||||
field: 'entity_id',
|
field: 'entity_id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Has SLO?',
|
name: 'Has SLO?',
|
||||||
field: 'slo_url',
|
field: 'slo_url',
|
||||||
renderer: 'boolean',
|
renderer: 'boolean',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ACS URL',
|
name: 'ACS URL',
|
||||||
field: 'acs_url',
|
field: 'acs_url',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
text: 'Create New',
|
text: 'Create New',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
icon: 'fa fa-times',
|
icon: 'fa fa-times',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
confirm: true,
|
confirm: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
this.form_definition = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Provider Name',
|
name: 'Provider Name',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
placeholder: 'Awesome External App',
|
placeholder: 'Awesome External App',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Entity ID',
|
name: 'Entity ID',
|
||||||
field: 'entity_id',
|
field: 'entity_id',
|
||||||
placeholder: 'https://my.awesome.app/saml/metadata.xml',
|
placeholder: 'https://my.awesome.app/saml/metadata.xml',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Assertion Consumer Service URL',
|
name: 'Assertion Consumer Service URL',
|
||||||
field: 'acs_url',
|
field: 'acs_url',
|
||||||
placeholder: 'https://my.awesome.app/saml/acs',
|
placeholder: 'https://my.awesome.app/saml/acs',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Single-Logout URL',
|
name: 'Single-Logout URL',
|
||||||
field: 'slo_url',
|
field: 'slo_url',
|
||||||
placeholder: 'https://my.awesome.app/saml/logout',
|
placeholder: 'https://my.awesome.app/saml/logout',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,95 +1,99 @@
|
|||||||
import CRUDBase from '../CRUDBase.js'
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
class AnnouncementResource extends CRUDBase {
|
class AnnouncementResource extends CRUDBase {
|
||||||
endpoint = '/api/v1/system/announcements'
|
constructor() {
|
||||||
required_fields = ['user_ids', 'group_ids', 'title', 'message', 'type']
|
super()
|
||||||
permission_base = 'v1:system:announcements'
|
|
||||||
|
|
||||||
item = 'System Announcement'
|
this.endpoint = '/api/v1/system/announcements'
|
||||||
plural = 'System Announcements'
|
this.required_fields = ['user_ids', 'group_ids', 'title', 'message', 'type']
|
||||||
|
this.permission_base = 'v1:system:announcements'
|
||||||
|
|
||||||
listing_definition = {
|
this.item = 'System Announcement'
|
||||||
display: `
|
this.plural = 'System Announcements'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
display: `
|
||||||
System announcements are administrative messages that you want all or some of your users to see. These messages can be delivered via e-mail, as a message after login, or as a system banner announcement.
|
System announcements are administrative messages that you want all or some of your users to see. These messages can be delivered via e-mail, as a message after login, or as a system banner announcement.
|
||||||
`,
|
`,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Title',
|
name: 'Title',
|
||||||
field: 'title',
|
field: 'title',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Message',
|
name: 'Message',
|
||||||
field: 'message',
|
field: 'message',
|
||||||
renderer: (message) => String(message).slice(0, 150),
|
renderer: (message) => String(message).slice(0, 150),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'main',
|
position: 'main',
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
text: 'Create New',
|
text: 'Create New',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'resource',
|
type: 'resource',
|
||||||
position: 'row',
|
position: 'row',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
icon: 'fa fa-times',
|
icon: 'fa fa-times',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
confirm: true,
|
confirm: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
form_definition = {
|
this.form_definition = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Title',
|
name: 'Title',
|
||||||
field: 'title',
|
field: 'title',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Message',
|
|
||||||
field: 'message',
|
|
||||||
type: 'textarea',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Users',
|
|
||||||
field: 'user_ids',
|
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/User',
|
|
||||||
display: (user) => `${user.last_name}, ${user.first_name} (${user.uid})`,
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'Message',
|
||||||
name: 'Groups',
|
field: 'message',
|
||||||
field: 'group_ids',
|
type: 'textarea',
|
||||||
type: 'select.dynamic.multiple',
|
|
||||||
options: {
|
|
||||||
resource: 'auth/Group',
|
|
||||||
display: (group) => `${group.name}`,
|
|
||||||
value: 'id',
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'Users',
|
||||||
name: 'Type',
|
field: 'user_ids',
|
||||||
field: 'type',
|
type: 'select.dynamic.multiple',
|
||||||
type: 'select',
|
options: {
|
||||||
options: [
|
resource: 'auth/User',
|
||||||
{ display: 'Login Intercept', value: 'login' },
|
display: (user) => `${user.last_name}, ${user.first_name} (${user.uid})`,
|
||||||
{ display: 'E-Mail', value: 'email' },
|
value: 'id',
|
||||||
{ display: 'System Banner', value: 'banner' },
|
},
|
||||||
],
|
},
|
||||||
},
|
{
|
||||||
],
|
name: 'Groups',
|
||||||
handlers: {
|
field: 'group_ids',
|
||||||
insert: {
|
type: 'select.dynamic.multiple',
|
||||||
action: 'redirect',
|
options: {
|
||||||
next: '/dash/c/listing/system/Announcement',
|
resource: 'auth/Group',
|
||||||
},
|
display: (group) => `${group.name}`,
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Type',
|
||||||
|
field: 'type',
|
||||||
|
type: 'select',
|
||||||
|
options: [
|
||||||
|
{display: 'Login Intercept', value: 'login'},
|
||||||
|
{display: 'E-Mail', value: 'email'},
|
||||||
|
{display: 'System Banner', value: 'banner'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
handlers: {
|
||||||
|
insert: {
|
||||||
|
action: 'redirect',
|
||||||
|
next: '/dash/c/listing/system/Announcement',
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
class Event {
|
class Event {
|
||||||
firings = []
|
|
||||||
subscriptions = []
|
|
||||||
|
|
||||||
constructor(name) {
|
constructor(name) {
|
||||||
this.name = name
|
this.name = name
|
||||||
|
this.firings = []
|
||||||
|
this.subscriptions = []
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe(handler) {
|
subscribe(handler) {
|
||||||
@ -22,7 +22,9 @@ class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class EventBusService {
|
class EventBusService {
|
||||||
_events = {}
|
constructor() {
|
||||||
|
this._events = {}
|
||||||
|
}
|
||||||
|
|
||||||
event(name) {
|
event(name) {
|
||||||
if ( !this._events[name] ) {
|
if ( !this._events[name] ) {
|
||||||
|
@ -2,7 +2,9 @@ import { event_bus } from './EventBus.service.js'
|
|||||||
import { auth_api } from './AuthApi.service.js'
|
import { auth_api } from './AuthApi.service.js'
|
||||||
|
|
||||||
class MessageService {
|
class MessageService {
|
||||||
listener_interval = 25000
|
constructor() {
|
||||||
|
this.listener_interval = 25000
|
||||||
|
}
|
||||||
|
|
||||||
alert({type, message, timeout = 0, on_dismiss = () => {} }) {
|
alert({type, message, timeout = 0, on_dismiss = () => {} }) {
|
||||||
event_bus.event('message.alert').fire({ type, message, timeout, on_dismiss })
|
event_bus.event('message.alert').fire({ type, message, timeout, on_dismiss })
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
class Session {
|
class Session {
|
||||||
data = {}
|
constructor() {
|
||||||
|
this.data = {}
|
||||||
|
}
|
||||||
|
|
||||||
init(data) {
|
init(data) {
|
||||||
this.data = data
|
this.data = data
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
class TranslateService {
|
class TranslateService {
|
||||||
_cache = {}
|
constructor() {
|
||||||
|
this._cache = {}
|
||||||
|
}
|
||||||
|
|
||||||
check_cache(...keys) {
|
check_cache(...keys) {
|
||||||
const obj = {}
|
const obj = {}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
class UtilityService {
|
class UtilityService {
|
||||||
_debounce_timeouts = {}
|
constructor() {
|
||||||
|
this._debounce_timeouts = {}
|
||||||
|
}
|
||||||
|
|
||||||
uuid() {
|
uuid() {
|
||||||
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||||
|
Loading…
Reference in New Issue
Block a user