This commit is mainly as a result of creating DN entries and improves some backend functions:

* Enable creation of new entries,
* Change all our ajax frames to go through /frames URI instead of /dn,
* Add our frame command to the encrypted DN,
* Automatically redirect to root URL when selecting a tree item and currently in another path (as a result of a prior POST activity),
* Some validation improvements DNExists/HasStructuralObjectClass
This commit is contained in:
2025-02-23 18:14:41 +11:00
parent f08fdb1bcd
commit 996d7bb1dc
27 changed files with 687 additions and 147 deletions

View File

@@ -0,0 +1,123 @@
@extends('layouts.dn')
@section('page_title')
@include('fragment.dn.header',['o'=>($oo=config('server')->fetch(old('container',$container)))])
@endsection
@section('main-content')
<x-error/>
<div class="row">
<div class="offset-1 col-10">
<div class="main-card mb-3 card">
<div class="card-header">
@lang('Create New Entry') - @lang('Step') {{ $step }}
</div>
<div class="card-body">
<form id="dn-create" method="POST" class="needs-validation" action="{{ url((int)$step === 2 ? 'entry/create' : 'entry/add') }}" enctype="multipart/form-data" novalidate>
@csrf
<input type="hidden" name="key" value="{{ Crypt::encryptString('*create|'.$container) }}">
<input type="hidden" name="step" value="{{ $step }}">
@switch($step)
@case(1)
<div class="row">
<div class="col-12 col-sm-6">
<x-form.select
id="objectclass"
name="objectclass[]"
:label="__('Select a Structural ObjectClass...')"
:options="($oc=config('server')->schema('objectclasses'))
->filter(fn($item)=>$item->isStructural())
->sortBy(fn($item)=>$item->name_lc)
->map(fn($item)=>['id'=>$item->name,'value'=>$item->name])"
multiple="false"
/>
</div>
</div>
@break
@case(2)
<x-attribute-type :edit="true" :o="$o->getObject('rdn')"/>
@foreach ($o->getVisibleAttributes() as $ao)
<x-attribute-type :edit="true" :o="$ao"/>
@endforeach
@include('fragment.dn.add_attr')
@break;
@endswitch
</form>
<div class="row d-none pt-3">
<div class="col-12 {{ $step > 1 ? 'offset-sm-2' : '' }} col-sm-4 col-lg-2">
<x-form.reset form="dn-create"/>
<x-form.submit action="Next" form="dn-create"/>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('page-scripts')
<script type="text/javascript">
var oc = {!! $oo->getObject('objectclass')->values !!};
function editmode() {
// Find all input items and turn off readonly
$('input.form-control').each(function() {
// Except for objectClass - @todo show an "X" instead
if ($(this)[0].name.match(/^objectclass/))
return;
$(this).attr('readonly',false);
});
// Our password type
$('div#userPassword .form-select').each(function() {
$(this).prop('disabled',false);
})
$('.row.d-none').removeClass('d-none');
$('.addable.d-none').removeClass('d-none');
$('.deletable.d-none').removeClass('d-none');
$('#newattr-select.d-none').removeClass('d-none');
}
$(document).ready(function() {
$('#newattr').on('change',function(item) {
$.ajax({
type: 'POST',
beforeSend: function() {},
success: function(data) {
$('#newattrs').append(data);
},
error: function(e) {
if (e.status != 412)
alert('That didnt work? Please try again....');
},
url: '{{ url('entry/attr/add') }}/'+item.target.value,
data: {
objectclasses: oc,
},
cache: false
});
// Remove the option from the list
$(this).find('[value="'+item.target.value+'"]').remove()
// If there are no more options
if ($(this).find("option").length === 1)
$('#newattr-select').remove();
});
editmode();
});
</script>
@append

View File

@@ -1,7 +1,7 @@
@extends('layouts.dn')
@section('page_title')
@include('fragment.dn.header')
@include('fragment.dn.header',['o'=>($o=config('server')->fetch($dn))])
@endsection
@section('main-content')
@@ -9,8 +9,6 @@
<x-updated/>
<x-error/>
<!-- @todo If we are redirected here, check old() and add back any attributes that were in the original submission -->
<div class="main-card mb-3 card">
<div class="card-body">
<div class="card-header-tabs">
@@ -34,31 +32,7 @@
<x-attribute-type :edit="true" :o="$ao"/>
@endforeach
<div id="newattrs"></div>
<!-- Add new attributes -->
<div class="row">
<div class="col-12 col-sm-1 col-md-2"></div>
<div class="col-12 col-sm-10 col-md-8">
<div class="d-none" id="newattr-select">
@if($o->getMissingAttributes()->count())
<div class="row">
<div class="col-12 bg-dark text-light p-2">
<i class="fas fa-plus-circle"></i> Add New Attribute
</div>
</div>
<div class="row">
<div class="col-12 pt-2">
<x-form.select id="newattr" label="Select from..." :options="$o->getMissingAttributes()->sortBy('name')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name_lc])"/>
</div>
</div>
@endif
</div>
</div>
<div class="col-2"></div>
</div>
@include('fragment.dn.add_attr')
</form>
<div class="row d-none pt-3">

View File

@@ -15,7 +15,7 @@
<div class="main-card mb-3 card">
<form id="import-form" action="{{ url('import/process/ldif') }}" method="POST" enctype="multipart/form-data">
@csrf
<input type="hidden" name="frame" value="import">
<input type="hidden" name="key" value="{{ Crypt::encryptString('*import|_NOP') }}">
<div class="card-header">
@lang('LDIF Import')

View File

@@ -1,10 +1,11 @@
@use(App\Classes\LDAP\Server)
@extends('layouts.dn')
@section('page_title')
<table class="table table-borderless">
<tr>
<td style="border-radius: 5px;"><div class="page-title-icon f32"><i class="fas fa-fingerprint"></i></div></td>
<td class="top text-end align-text-top p-0 pt-2"><strong>{{ \App\Classes\LDAP\Server::schemaDN() }}</strong></td>
<td class="top text-end align-text-top p-0 pt-2"><strong>{{ Server::schemaDN() }}</strong></td>
</tr>
</table>
@endsection