Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
a61f5e9b97 | |||
d845d87a6e | |||
b501dfe824 | |||
3fad9770a3 | |||
b1d153aa9f | |||
8b0af505a1 | |||
f0eaff7d42 | |||
352bbe2b75 | |||
0fe4894192 | |||
a7be4e00b4 | |||
2abc321eca | |||
6b2fb8dee4 | |||
66537dcec8 | |||
1bf8830887 | |||
c4d28c8a23 | |||
29c460fd4b | |||
3196b10aed | |||
f41b484dc4 | |||
855d7ae75c | |||
ffa8cdc826 | |||
8f39603f9f | |||
bcea6de791 | |||
28f4869628 | |||
cf535286c5 | |||
633513d3e9 | |||
705bfb2d64 | |||
3a3bf2addb | |||
5bb573100b | |||
a57ee78492 | |||
eab4f0427c | |||
fd2c5d1286 | |||
b35b44b2b8 | |||
ce66dcb2b5 | |||
56a91f853c | |||
81e0e58650 | |||
1470170928 | |||
85c7132b30 |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -10,6 +10,9 @@ assignees: ''
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is. (One issue per report please.)
|
||||
|
||||
**Version of PLA**
|
||||
What version of PLA are you using. Are you using the docker container, an distribution package or running from GIT source?
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
@ -61,6 +61,7 @@ Support is known for these LDAP servers:
|
||||
- [X] OpenLDAP
|
||||
- [X] OpenDJ
|
||||
- [ ] Microsoft Active Directory
|
||||
- [ ] 389 Directory Server
|
||||
|
||||
If there is an LDAP server that you have that you would like to have supported, please open an issue to request it.
|
||||
You might need to provide access, provide a copy or instructions to get an environment for testing. If you have enabled
|
||||
|
@ -7,39 +7,39 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\Schema\AttributeType;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Represents an attribute of an LDAP Object
|
||||
*/
|
||||
class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
class Attribute implements \Countable, \ArrayAccess
|
||||
{
|
||||
// Attribute Name
|
||||
protected string $name;
|
||||
private int $counter = 0;
|
||||
|
||||
// Is this attribute an internal attribute
|
||||
protected(set) bool $is_internal = FALSE;
|
||||
protected(set) bool $no_attr_tags = FALSE;
|
||||
|
||||
// MIN/MAX number of values
|
||||
protected(set) int $min_values_count = 0;
|
||||
protected(set) int $max_values_count = 0;
|
||||
|
||||
// RFC3866 Language Tags
|
||||
/* @deprecated use $values/$values_old when playing with language tags */
|
||||
protected Collection $lang_tags;
|
||||
|
||||
// The schema's representation of this attribute
|
||||
protected(set) ?AttributeType $schema;
|
||||
|
||||
// The DN this object is in
|
||||
protected(set) string $dn;
|
||||
// The old values for this attribute - helps with isDirty() to determine if there is an update pending
|
||||
protected(set) Collection $values_old;
|
||||
private Collection $_values_old;
|
||||
// Current Values
|
||||
public Collection $values;
|
||||
private Collection $_values;
|
||||
// The objectclasses of the entry that has this attribute
|
||||
protected(set) Collection $oc;
|
||||
|
||||
private const SYNTAX_CERTIFICATE = '1.3.6.1.4.1.1466.115.121.1.8';
|
||||
private const SYNTAX_CERTIFICATE_LIST = '1.3.6.1.4.1.1466.115.121.1.9';
|
||||
|
||||
/*
|
||||
# Has the attribute been modified
|
||||
protected $modified = false;
|
||||
@ -103,11 +103,10 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
{
|
||||
$this->dn = $dn;
|
||||
$this->name = $name;
|
||||
$this->values_old = collect($values);
|
||||
$this->_values = collect($values);
|
||||
$this->_values_old = collect($values);
|
||||
|
||||
$this->values = collect();
|
||||
$this->oc = collect($oc);
|
||||
$this->lang_tags = collect();
|
||||
|
||||
$this->schema = (new Server)
|
||||
->schema('attributetypes',$name);
|
||||
@ -127,6 +126,11 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
*/
|
||||
}
|
||||
|
||||
public function __call(string $name,array $arguments)
|
||||
{
|
||||
abort(555,'Method not handled: '.$name);
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
@ -152,59 +156,51 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
'required_by' => $this->schema?->required_by_object_classes ?: collect(),
|
||||
// Used in Object Classes
|
||||
'used_in' => $this->schema?->used_in_object_classes ?: collect(),
|
||||
// The current attribute values
|
||||
'values' => $this->no_attr_tags ? $this->tagValues() : $this->_values,
|
||||
// The original attribute values
|
||||
'values_old' => $this->no_attr_tags ? $this->tagValuesOld() : $this->_values_old,
|
||||
|
||||
default => throw new \Exception('Unknown key:' . $key),
|
||||
};
|
||||
}
|
||||
|
||||
public function __set(string $key,mixed $values): void
|
||||
{
|
||||
switch ($key) {
|
||||
case 'values':
|
||||
$this->_values = $values;
|
||||
break;
|
||||
|
||||
case 'values_old':
|
||||
$this->_values_old = $values;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('Unknown key:'.$key);
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addValue(string $value): void
|
||||
{
|
||||
$this->values->push($value);
|
||||
}
|
||||
|
||||
public function current(): mixed
|
||||
{
|
||||
return $this->values->get($this->counter);
|
||||
}
|
||||
|
||||
public function next(): void
|
||||
{
|
||||
$this->counter++;
|
||||
}
|
||||
|
||||
public function key(): mixed
|
||||
{
|
||||
return $this->counter;
|
||||
}
|
||||
|
||||
public function valid(): bool
|
||||
{
|
||||
return $this->values->has($this->counter);
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->counter = 0;
|
||||
}
|
||||
/* INTERFACE */
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->values->count();
|
||||
return $this->_values->dot()->count();
|
||||
}
|
||||
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return ! is_null($this->values->has($offset));
|
||||
return $this->_values->dot()->has($offset);
|
||||
}
|
||||
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->values->get($offset);
|
||||
return $this->_values->dot()->get($offset);
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
@ -217,15 +213,36 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
// We cannot clear values using array syntax
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function addValue(string $tag,array $values): void
|
||||
{
|
||||
$this->_values->put(
|
||||
$tag,
|
||||
array_unique(array_merge($this->_values
|
||||
->get($tag,[]),$values)));
|
||||
}
|
||||
|
||||
public function addValueOld(string $tag,array $values): void
|
||||
{
|
||||
$this->_values_old->put(
|
||||
$tag,
|
||||
array_unique(array_merge($this->_values_old
|
||||
->get($tag,[]),$values)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hints about this attribute, ie: RDN, Required, etc
|
||||
*
|
||||
* @return array
|
||||
* @return Collection
|
||||
*/
|
||||
public function hints(): array
|
||||
public function hints(): Collection
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
if ($this->is_internal)
|
||||
return $result;
|
||||
|
||||
// Is this Attribute an RDN
|
||||
if ($this->is_rdn)
|
||||
$result->put(__('rdn'),__('This attribute is required for the RDN'));
|
||||
@ -236,11 +253,11 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
if ($this->required()->count())
|
||||
$result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required()->join(', ')));
|
||||
|
||||
// This attribute has language tags
|
||||
if ($this->lang_tags->count())
|
||||
$result->put(__('language tags'),sprintf('%s: %d',__('This Attribute has Language Tags'),$this->lang_tags->count()));
|
||||
// If this attribute is a dynamic attribute
|
||||
if ($this->isDynamic())
|
||||
$result->put(__('dynamic'),__('These are dynamic values present as a result of another attribute'));
|
||||
|
||||
return $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,8 +267,22 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
*/
|
||||
public function isDirty(): bool
|
||||
{
|
||||
return ($this->values_old->count() !== $this->values->count())
|
||||
|| ($this->values->diff($this->values_old)->count() !== 0);
|
||||
return (($a=$this->values_old->dot()->filter())->keys()->count() !== ($b=$this->values->dot()->filter())->keys()->count())
|
||||
|| ($a->count() !== $b->count())
|
||||
|| ($a->diff($b)->count() !== 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Are these values as a result of a dynamic attribute
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDynamic(): bool
|
||||
{
|
||||
return $this->schema->used_in_object_classes
|
||||
->keys()
|
||||
->intersect($this->schema->heirachy($this->oc))
|
||||
->count() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,9 +311,14 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
*/
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
$view = view()->exists($x='components.attribute.'.$this->name_lc)
|
||||
? view($x)
|
||||
: view('components.attribute');
|
||||
$view = match ($this->schema->syntax_oid) {
|
||||
self::SYNTAX_CERTIFICATE => view('components.syntax.certificate'),
|
||||
self::SYNTAX_CERTIFICATE_LIST => view('components.syntax.certificatelist'),
|
||||
|
||||
default => view()->exists($x = 'components.attribute.' . $this->name_lc)
|
||||
? view($x)
|
||||
: view('components.attribute'),
|
||||
};
|
||||
|
||||
return $view
|
||||
->with('o',$this)
|
||||
@ -291,14 +327,19 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
->with('new',$new);
|
||||
}
|
||||
|
||||
public function render_item_old(int $key): ?string
|
||||
public function render_item_old(string $dotkey): ?string
|
||||
{
|
||||
return Arr::get($this->values_old,$key);
|
||||
return match ($this->schema->syntax_oid) {
|
||||
self::SYNTAX_CERTIFICATE => join("\n",str_split(base64_encode(Arr::get($this->values_old->dot(),$dotkey)),80)),
|
||||
self::SYNTAX_CERTIFICATE_LIST => join("\n",str_split(base64_encode(Arr::get($this->values_old->dot(),$dotkey)),80)),
|
||||
|
||||
default => Arr::get($this->values_old->dot(),$dotkey),
|
||||
};
|
||||
}
|
||||
|
||||
public function render_item_new(int $key): ?string
|
||||
public function render_item_new(string $dotkey): ?string
|
||||
{
|
||||
return Arr::get($this->values,$key);
|
||||
return Arr::get($this->values->dot(),$dotkey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -310,20 +351,21 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
{
|
||||
// If we dont have any objectclasses then we cant know if it is required
|
||||
return $this->oc->count()
|
||||
? $this->oc->intersect($this->schema->required_by_object_classes->keys())->sort()
|
||||
? $this->oc->intersect($this->required_by->keys())->sort()
|
||||
: collect();
|
||||
}
|
||||
|
||||
/**
|
||||
* If this attribute has RFC3866 Language Tags, this will enable those values to be captured
|
||||
*
|
||||
* @param string $tag
|
||||
* @param array $value
|
||||
* @return void
|
||||
* @deprecated
|
||||
*/
|
||||
public function setLangTag(string $tag,array $value): void
|
||||
public function tagValues(string $tag=Entry::TAG_NOTAG): Collection
|
||||
{
|
||||
$this->lang_tags->put($tag,$value);
|
||||
return collect($this->_values
|
||||
->filter(fn($item,$key)=>($key===$tag))
|
||||
->get($tag,[]));
|
||||
}
|
||||
|
||||
public function tagValuesOld(string $tag=Entry::TAG_NOTAG): Collection
|
||||
{
|
||||
return collect($this->_values_old
|
||||
->filter(fn($item,$key)=>($key===$tag))
|
||||
->get($tag,[]));
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ namespace App\Classes\LDAP\Attribute\Binary;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Binary;
|
||||
use App\Ldap\Entry;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
/**
|
||||
@ -14,13 +15,14 @@ final class JpegPhoto extends Binary
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG): View
|
||||
{
|
||||
return view('components.attribute.binary.jpegphoto')
|
||||
->with('o',$this)
|
||||
->with('edit',$edit)
|
||||
->with('old',$old)
|
||||
->with('new',$new)
|
||||
->with('langtag',$langtag)
|
||||
->with('f',new \finfo);
|
||||
}
|
||||
}
|
47
app/Classes/LDAP/Attribute/Certificate.php
Normal file
47
app/Classes/LDAP/Attribute/Certificate.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values is a binary user certificate
|
||||
*/
|
||||
final class Certificate extends Attribute
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
private array $_object = [];
|
||||
|
||||
public function certificate(int $key=0): string
|
||||
{
|
||||
return sprintf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----",
|
||||
join("\n",str_split(base64_encode(Arr::get($this->values_old,'binary.'.$key)),80))
|
||||
);
|
||||
}
|
||||
|
||||
public function cert_info(string $index,int $key=0): mixed
|
||||
{
|
||||
if (! array_key_exists($key,$this->_object))
|
||||
$this->_object[$key] = openssl_x509_parse(openssl_x509_read($this->certificate($key)));
|
||||
|
||||
|
||||
return Arr::get($this->_object[$key],$index);
|
||||
}
|
||||
|
||||
public function expires($key=0): Carbon
|
||||
{
|
||||
return Carbon::createFromTimestampUTC($this->cert_info('validTo_time_t',$key));
|
||||
}
|
||||
|
||||
public function subject($key=0): string
|
||||
{
|
||||
$subject = collect($this->cert_info('subject',$key))->reverse();
|
||||
|
||||
return $subject->map(fn($item,$key)=>sprintf("%s=%s",$key,$item))->join(',');
|
||||
}
|
||||
}
|
17
app/Classes/LDAP/Attribute/CertificateList.php
Normal file
17
app/Classes/LDAP/Attribute/CertificateList.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values is a binary user certificate
|
||||
*/
|
||||
final class CertificateList extends Attribute
|
||||
{
|
||||
use MD5Updates;
|
||||
}
|
@ -20,13 +20,22 @@ class Factory
|
||||
* Map of attributes to appropriate class
|
||||
*/
|
||||
public const map = [
|
||||
'authorityrevocationlist' => CertificateList::class,
|
||||
'cacertificate' => Certificate::class,
|
||||
'certificaterevocationlist' => CertificateList::class,
|
||||
'createtimestamp' => Internal\Timestamp::class,
|
||||
'creatorsname' => Internal\DN::class,
|
||||
'configcontext' => Schema\Generic::class,
|
||||
'contextcsn' => Internal\CSN::class,
|
||||
'entrycsn' => Internal\CSN::class,
|
||||
'entrydn' => Internal\DN::class,
|
||||
'entryuuid' => Internal\UUID::class,
|
||||
'etag' => Internal\Etag::class,
|
||||
'krblastfailedauth' => Attribute\NoAttrTags\Generic::class,
|
||||
'krblastpwdchange' => Attribute\NoAttrTags\Generic::class,
|
||||
'krblastsuccessfulauth' => Attribute\NoAttrTags\Generic::class,
|
||||
'krbpasswordexpiration' => Attribute\NoAttrTags\Generic::class,
|
||||
'krbloginfailedcount' => Attribute\NoAttrTags\Generic::class,
|
||||
'krbprincipalkey' => KrbPrincipalKey::class,
|
||||
'krbticketflags' => KrbTicketFlags::class,
|
||||
'gidnumber' => GidNumber::class,
|
||||
@ -34,6 +43,8 @@ class Factory
|
||||
'jpegphoto' => Binary\JpegPhoto::class,
|
||||
'modifytimestamp' => Internal\Timestamp::class,
|
||||
'modifiersname' => Internal\DN::class,
|
||||
'monitorcontext' => Schema\Generic::class,
|
||||
'namingcontexts' => Schema\Generic::class,
|
||||
'numsubordinates' => Internal\NumSubordinates::class,
|
||||
'objectclass' => ObjectClass::class,
|
||||
'pwdpolicysubentry' => Internal\PwdPolicySubentry::class,
|
||||
@ -42,7 +53,9 @@ class Factory
|
||||
'supportedcontrol' => Schema\OID::class,
|
||||
'supportedextension' => Schema\OID::class,
|
||||
'supportedfeatures' => Schema\OID::class,
|
||||
'supportedldapversion' => Schema\Generic::class,
|
||||
'supportedsaslmechanisms' => Schema\Mechanisms::class,
|
||||
'usercertificate' => Certificate::class,
|
||||
'userpassword' => Password::class,
|
||||
];
|
||||
|
||||
|
@ -9,4 +9,5 @@ use App\Classes\LDAP\Attribute;
|
||||
*/
|
||||
final class GidNumber extends Attribute
|
||||
{
|
||||
protected(set) bool $no_attr_tags = FALSE;
|
||||
}
|
@ -12,6 +12,7 @@ use App\Classes\LDAP\Attribute;
|
||||
abstract class Internal extends Attribute
|
||||
{
|
||||
protected(set) bool $is_internal = TRUE;
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ final class KrbPrincipalKey extends Attribute
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
return view('components.attribute.krbprincipalkey')
|
||||
@ -24,18 +26,16 @@ final class KrbPrincipalKey extends Attribute
|
||||
->with('new',$new);
|
||||
}
|
||||
|
||||
public function render_item_old(int $key): ?string
|
||||
public function render_item_old(string $dotkey): ?string
|
||||
{
|
||||
$pw = Arr::get($this->values_old,$key);
|
||||
return $pw
|
||||
return parent::render_item_old($dotkey)
|
||||
? str_repeat('*',16)
|
||||
: NULL;
|
||||
}
|
||||
|
||||
public function render_item_new(int $key): ?string
|
||||
public function render_item_new(string $dotkey): ?string
|
||||
{
|
||||
$pw = Arr::get($this->values,$key);
|
||||
return $pw
|
||||
return parent::render_item_new($dotkey)
|
||||
? str_repeat('*',16)
|
||||
: NULL;
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose value is a Kerberos Ticket Flag
|
||||
@ -13,6 +13,8 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
final class KrbTicketFlags extends Attribute
|
||||
{
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
|
||||
private const DISALLOW_POSTDATED = 0x00000001;
|
||||
private const DISALLOW_FORWARDABLE = 0x00000002;
|
||||
private const DISALLOW_TGT_BASED = 0x00000004;
|
||||
|
13
app/Classes/LDAP/Attribute/NoAttrTags/Generic.php
Normal file
13
app/Classes/LDAP/Attribute/NoAttrTags/Generic.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\NoAttrTags;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
|
||||
/**
|
||||
* Represents an Attribute that doesnt have Lang Tags
|
||||
*/
|
||||
class Generic extends Attribute
|
||||
{
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
}
|
@ -6,12 +6,15 @@ use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Represents an ObjectClass Attribute
|
||||
*/
|
||||
final class ObjectClass extends Attribute
|
||||
{
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
|
||||
// The schema ObjectClasses for this objectclass of a DN
|
||||
protected Collection $oc_schema;
|
||||
|
||||
@ -21,25 +24,39 @@ final class ObjectClass extends Attribute
|
||||
* @param string $dn DN this attribute is used in
|
||||
* @param string $name Name of the attribute
|
||||
* @param array $values Current Values
|
||||
* @param array $oc The objectclasses that the DN of this attribute has
|
||||
* @param array $oc The objectclasses that the DN of this attribute has (ignored for objectclasses)
|
||||
*/
|
||||
public function __construct(string $dn,string $name,array $values,array $oc=[])
|
||||
{
|
||||
parent::__construct($dn,$name,$values,['top']);
|
||||
|
||||
$this->oc_schema = config('server')
|
||||
->schema('objectclasses')
|
||||
->filter(fn($item)=>$this->values->merge($this->values_old)->unique()->contains($item->name));
|
||||
$this->set_oc_schema($this->tagValuesOld());
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
'structural' => $this->oc_schema->filter(fn($item) => $item->isStructural()),
|
||||
'structural' => $this->oc_schema->filter(fn($item)=>$item->isStructural()),
|
||||
default => parent::__get($key),
|
||||
};
|
||||
}
|
||||
|
||||
public function __set(string $key,mixed $values): void
|
||||
{
|
||||
switch ($key) {
|
||||
case 'values':
|
||||
parent::__set($key,$values);
|
||||
|
||||
// We need to populate oc_schema, if we are a new OC and thus dont have any old values
|
||||
if (! $this->values_old->count() && $this->values->count())
|
||||
$this->set_oc_schema($this->tagValues());
|
||||
|
||||
break;
|
||||
|
||||
default: parent::__set($key,$values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a specific value the structural objectclass
|
||||
*
|
||||
@ -58,7 +75,15 @@ final class ObjectClass extends Attribute
|
||||
return view('components.attribute.objectclass')
|
||||
->with('o',$this)
|
||||
->with('edit',$edit)
|
||||
->with('langtag',Entry::TAG_NOTAG)
|
||||
->with('old',$old)
|
||||
->with('new',$new);
|
||||
}
|
||||
|
||||
private function set_oc_schema(Collection $tv): void
|
||||
{
|
||||
$this->oc_schema = config('server')
|
||||
->schema('objectclasses')
|
||||
->filter(fn($item)=>$tv->contains($item->name));
|
||||
}
|
||||
}
|
@ -15,6 +15,9 @@ use App\Traits\MD5Updates;
|
||||
final class Password extends Attribute
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
|
||||
private const password_helpers = 'Classes/LDAP/Attribute/Password';
|
||||
public const commands = 'App\\Classes\\LDAP\\Attribute\\Password\\';
|
||||
|
||||
@ -85,19 +88,23 @@ final class Password extends Attribute
|
||||
->with('helpers',static::helpers()->map(fn($item,$key)=>['id'=>$key,'value'=>$key])->sort());
|
||||
}
|
||||
|
||||
public function render_item_old(int $key): ?string
|
||||
public function render_item_old(string $dotkey): ?string
|
||||
{
|
||||
$pw = Arr::get($this->values_old,$key);
|
||||
$pw = parent::render_item_old($dotkey);
|
||||
|
||||
return $pw
|
||||
? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '').str_repeat('*',16))
|
||||
? (((($x=$this->hash($pw)) && ($x::id() === '*clear*')) ? sprintf('{%s}',$x::shortid()) : '')
|
||||
.str_repeat('*',16))
|
||||
: NULL;
|
||||
}
|
||||
|
||||
public function render_item_new(int $key): ?string
|
||||
public function render_item_new(string $dotkey): ?string
|
||||
{
|
||||
$pw = Arr::get($this->values,$key);
|
||||
$pw = parent::render_item_new($dotkey);
|
||||
|
||||
return $pw
|
||||
? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '').str_repeat('*',16))
|
||||
? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '')
|
||||
.str_repeat('*',16))
|
||||
: NULL;
|
||||
}
|
||||
}
|
@ -24,11 +24,11 @@ final class RDN extends Attribute
|
||||
};
|
||||
}
|
||||
|
||||
public function hints(): array
|
||||
public function hints(): Collection
|
||||
{
|
||||
return [
|
||||
return collect([
|
||||
'required' => __('RDN is required')
|
||||
];
|
||||
]);
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
|
@ -14,6 +14,7 @@ use App\Classes\LDAP\Attribute;
|
||||
abstract class Schema extends Attribute
|
||||
{
|
||||
protected bool $internal = TRUE;
|
||||
protected(set) bool $no_attr_tags = TRUE;
|
||||
|
||||
protected static function _get(string $filename,string $string,string $key): ?string
|
||||
{
|
||||
@ -30,7 +31,7 @@ abstract class Schema extends Attribute
|
||||
while (! feof($f)) {
|
||||
$line = trim(fgets($f));
|
||||
|
||||
if (! $line OR preg_match('/^#/',$line))
|
||||
if ((! $line) || preg_match('/^#/',$line))
|
||||
continue;
|
||||
|
||||
$fields = explode(':',$line);
|
||||
@ -41,12 +42,15 @@ abstract class Schema extends Attribute
|
||||
'desc'=>Arr::get($fields,3,__('No description available, can you help with one?')),
|
||||
]);
|
||||
}
|
||||
|
||||
fclose($f);
|
||||
|
||||
return $result;
|
||||
});
|
||||
|
||||
return Arr::get(($array ? $array->get($string) : []),$key);
|
||||
return Arr::get(($array ? $array->get($string) : []),
|
||||
$key,
|
||||
__('No description available, can you help with one?'));
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
|
20
app/Classes/LDAP/Attribute/Schema/Generic.php
Normal file
20
app/Classes/LDAP/Attribute/Schema/Generic.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Schema;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Schema;
|
||||
|
||||
/**
|
||||
* Represents a Generic Schema Attribute
|
||||
*/
|
||||
class Generic extends Schema
|
||||
{
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
// @note Schema attributes cannot be edited
|
||||
return view('components.attribute.schema.generic')
|
||||
->with('o',$this);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ namespace App\Classes\LDAP\Export;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use App\Classes\LDAP\Export;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Export from LDAP using an LDIF format
|
||||
@ -41,13 +42,25 @@ class LDIF extends Export
|
||||
|
||||
// Display Attributes
|
||||
foreach ($o->getObjects() as $ao) {
|
||||
foreach ($ao->values as $value) {
|
||||
$result .= $this->multiLineDisplay(
|
||||
Str::isAscii($value)
|
||||
? sprintf('%s: %s',$ao->name,$value)
|
||||
: sprintf('%s:: %s',$ao->name,base64_encode($value))
|
||||
,$this->br);
|
||||
}
|
||||
if ($ao->no_attr_tags)
|
||||
foreach ($ao->values as $value) {
|
||||
$result .= $this->multiLineDisplay(
|
||||
Str::isAscii($value)
|
||||
? sprintf('%s: %s',$ao->name,$value)
|
||||
: sprintf('%s:: %s',$ao->name,base64_encode($value))
|
||||
,$this->br);
|
||||
}
|
||||
|
||||
else
|
||||
foreach ($ao->values as $tag => $tagvalues) {
|
||||
foreach ($tagvalues as $value) {
|
||||
$result .= $this->multiLineDisplay(
|
||||
Str::isAscii($value)
|
||||
? sprintf('%s: %s',$ao->name.(($tag !== Entry::TAG_NOTAG) ? ';'.$tag : ''),$value)
|
||||
: sprintf('%s:: %s',$ao->name.(($tag !== Entry::TAG_NOTAG) ? ';'.$tag : ''),base64_encode($value))
|
||||
,$this->br);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,6 @@ class LDIF extends Import
|
||||
$base64encoded = FALSE;
|
||||
$attribute = NULL;
|
||||
$value = '';
|
||||
|
||||
// Else its a blank line
|
||||
}
|
||||
|
||||
continue;
|
||||
@ -69,7 +67,7 @@ class LDIF extends Import
|
||||
$m = [];
|
||||
preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m);
|
||||
|
||||
switch ($x=Arr::get($m,1)) {
|
||||
switch (Arr::get($m,1)) {
|
||||
case 'changetype':
|
||||
if ($m[2] !== ':')
|
||||
throw new GeneralException(sprintf('ChangeType cannot be base64 encoded set at [%d]. (line %d)',$version,$c));
|
||||
@ -133,7 +131,6 @@ class LDIF extends Import
|
||||
|
||||
// Start of a new attribute
|
||||
$base64encoded = ($m[2] === '::');
|
||||
// @todo Need to parse attributes with ';' options
|
||||
$attribute = $m[1];
|
||||
$value = $m[3];
|
||||
|
||||
@ -159,8 +156,8 @@ class LDIF extends Import
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function readEntry() {
|
||||
static $haveVersion = false;
|
||||
public function xreadEntry() {
|
||||
static $haveVersion = FALSE;
|
||||
|
||||
if ($lines = $this->nextLines()) {
|
||||
|
||||
@ -179,7 +176,7 @@ class LDIF extends Import
|
||||
} else
|
||||
$changetype = 'add';
|
||||
|
||||
$this->template = new Template($this->server_id,null,null,$changetype);
|
||||
$this->template = new Template($this->server_id,NULL,NULL,$changetype);
|
||||
|
||||
switch ($changetype) {
|
||||
case 'add':
|
||||
@ -201,7 +198,7 @@ class LDIF extends Import
|
||||
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
|
||||
|
||||
$this->template->setDN($dn);
|
||||
$this->template->accept(false,true);
|
||||
$this->template->accept(FALSE,TRUE);
|
||||
|
||||
return $this->getModifyDetails($lines);
|
||||
|
||||
@ -221,13 +218,13 @@ class LDIF extends Import
|
||||
|
||||
default:
|
||||
if (! $server->dnExists($dn))
|
||||
return $this->error(_('Unkown change type'),$lines);
|
||||
return $this->error(_('Unknown change type'),$lines);
|
||||
}
|
||||
|
||||
} else
|
||||
return $this->error(_('A valid dn line is required'),$lines);
|
||||
|
||||
} else
|
||||
return false;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
@ -6,6 +6,9 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Represents an LDAP AttributeType
|
||||
*
|
||||
@ -341,6 +344,11 @@ final class AttributeType extends Base {
|
||||
$this->used_in_object_classes->put($name,$structural);
|
||||
}
|
||||
|
||||
private function factory(): Attribute
|
||||
{
|
||||
return Attribute\Factory::create(dn:'',attribute:$this->name,values:[]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of attributes that are an alias for this attribute (if any).
|
||||
*
|
||||
@ -478,6 +486,28 @@ final class AttributeType extends Base {
|
||||
return $this->used_in_object_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a list of objectclasses return all parent objectclasses as well
|
||||
*
|
||||
* @param Collection $ocs
|
||||
* @return Collection
|
||||
*/
|
||||
public function heirachy(Collection $ocs): Collection
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
foreach ($ocs as $oc) {
|
||||
$schema = config('server')
|
||||
->schema('objectclasses',$oc)
|
||||
->getParents(TRUE)
|
||||
->pluck('name');
|
||||
|
||||
$result = $result->merge($schema)->push($oc);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @deprecated use $this->forced_as_may
|
||||
@ -547,23 +577,21 @@ final class AttributeType extends Base {
|
||||
public function validation(array $array): ?array
|
||||
{
|
||||
// For each item in array, we need to get the OC hierarchy
|
||||
$heirachy = collect($array)
|
||||
->filter()
|
||||
->map(fn($item)=>config('server')
|
||||
->schema('objectclasses',$item)
|
||||
->getSupClasses()
|
||||
->push($item))
|
||||
$heirachy = $this->heirachy(collect($array)
|
||||
->flatten()
|
||||
->unique();
|
||||
->filter());
|
||||
|
||||
// Get any config validation
|
||||
$validation = collect(Arr::get(config('ldap.validation'),$this->name_lc,[]));
|
||||
|
||||
$nolangtag = sprintf('%s.%s.0',$this->name_lc,Entry::TAG_NOTAG);
|
||||
|
||||
// Add in schema required by conditions
|
||||
if (($heirachy->intersect($this->required_by_object_classes->keys())->count() > 0)
|
||||
&& (! collect($validation->get($this->name_lc))->contains('required'))) {
|
||||
$validation
|
||||
->prepend(array_merge(['required','min:1'],$validation->get($this->name_lc.'.0',[])),$this->name_lc.'.0')
|
||||
->prepend(array_merge(['required','array','min:1'],$validation->get($this->name_lc,[])),$this->name_lc);
|
||||
->prepend(array_merge(['required','min:1'],$validation->get($nolangtag,[])),$nolangtag)
|
||||
->prepend(array_merge(['required','array','min:1',($this->factory()->no_attr_tags ? 'max:1' : NULL)],$validation->get($this->name_lc,[])),$this->name_lc);
|
||||
}
|
||||
|
||||
return $validation->toArray();
|
||||
|
@ -209,7 +209,8 @@ final class Server
|
||||
/**
|
||||
* Obtain the rootDSE for the server, that gives us server information
|
||||
*
|
||||
* @param null $connection
|
||||
* @param string|null $connection
|
||||
* @param Carbon|null $cachetime
|
||||
* @return Entry|null
|
||||
* @throws ObjectNotFoundException
|
||||
* @testedin TranslateOidTest::testRootDSE();
|
||||
@ -230,7 +231,7 @@ final class Server
|
||||
/**
|
||||
* Get the Schema DN
|
||||
*
|
||||
* @param $connection
|
||||
* @param string|null $connection
|
||||
* @return string
|
||||
* @throws ObjectNotFoundException
|
||||
*/
|
||||
@ -245,16 +246,21 @@ final class Server
|
||||
* Query the server for a DN and return its children and if those children have children.
|
||||
*
|
||||
* @param string $dn
|
||||
* @param array $attrs
|
||||
* @return LDAPCollection|NULL
|
||||
*/
|
||||
public function children(string $dn): ?LDAPCollection
|
||||
public function children(string $dn,array $attrs=['dn']): ?LDAPCollection
|
||||
{
|
||||
return ($x=(new Entry)
|
||||
->on($this->connection)
|
||||
->cache(Carbon::now()->addSeconds(Config::get('ldap.cache.time')))
|
||||
->select(['*','hassubordinates'])
|
||||
->select(array_merge($attrs,[
|
||||
'hassubordinates', // Needed for the tree to know if an entry has children
|
||||
'c' // Needed for the tree to show icons for countries
|
||||
]))
|
||||
->setDn($dn)
|
||||
->list()
|
||||
->orderBy('dn')
|
||||
->get()) ? $x : NULL;
|
||||
}
|
||||
|
||||
@ -528,7 +534,6 @@ final class Server
|
||||
*
|
||||
* @param string $oid
|
||||
* @return LDAPSyntax|null
|
||||
* @throws InvalidUsage
|
||||
*/
|
||||
public function schemaSyntaxName(string $oid): ?LDAPSyntax
|
||||
{
|
||||
|
@ -97,7 +97,6 @@ class APIController extends Controller
|
||||
/**
|
||||
* Return the required and additional attributes for an object class
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $objectclass
|
||||
* @return array
|
||||
*/
|
||||
|
@ -57,11 +57,12 @@ class HomeController extends Controller
|
||||
|
||||
$o = new Entry;
|
||||
|
||||
if (count(array_filter($x=old('objectclass',$request->objectclass)))) {
|
||||
if (count($x=array_filter(old('objectclass',$request->objectclass)))) {
|
||||
$o->objectclass = $x;
|
||||
|
||||
// Also add in our required attributes
|
||||
foreach($o->getAvailableAttributes()->filter(fn($item)=>$item->required) as $ao)
|
||||
$o->{$ao->name} = '';
|
||||
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
|
||||
|
||||
$o->setRDNBase($key['dn']);
|
||||
}
|
||||
@ -92,10 +93,12 @@ class HomeController extends Controller
|
||||
|
||||
return $request->noheader
|
||||
? view(sprintf('components.attribute.widget.%s',$id))
|
||||
->with('o',Factory::create($dn,$id,[],$request->objectclasses))
|
||||
->with('o',Factory::create(dn: $dn,attribute: $id,values: [],oc: $request->objectclasses))
|
||||
->with('value',$request->value)
|
||||
->with('langtag',Entry::TAG_NOTAG)
|
||||
->with('loop',$xx)
|
||||
: new AttributeType(Factory::create($dn,$id,[],$request->objectclasses),TRUE)->render();
|
||||
: new AttributeType(Factory::create($dn,$id,[],$request->objectclasses),new: TRUE,edit: TRUE)
|
||||
->render();
|
||||
}
|
||||
|
||||
public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse
|
||||
@ -188,8 +191,6 @@ class HomeController extends Controller
|
||||
|
||||
$result = (new Entry)
|
||||
->query()
|
||||
//->cache(Carbon::now()->addSeconds(Config::get('ldap.cache.time')))
|
||||
//->select(['*'])
|
||||
->setDn($dn)
|
||||
->recursive()
|
||||
->get();
|
||||
@ -237,7 +238,7 @@ class HomeController extends Controller
|
||||
$password = $o->getObject('userpassword');
|
||||
|
||||
$result = collect();
|
||||
foreach ($password as $key => $value) {
|
||||
foreach ($password->values->dot() as $key => $value) {
|
||||
$hash = $password->hash($value);
|
||||
$compare = Arr::get($request->password,$key);
|
||||
//Log::debug(sprintf('comparing [%s] with [%s] type [%s]',$value,$compare,$hash::id()),['object'=>$hash]);
|
||||
@ -269,19 +270,22 @@ class HomeController extends Controller
|
||||
// We need to process and encrypt the password
|
||||
if ($request->userpassword) {
|
||||
$passwords = [];
|
||||
foreach ($request->userpassword as $key => $value) {
|
||||
$po = $o->getObject('userpassword');
|
||||
foreach (Arr::dot($request->userpassword) as $dotkey => $value) {
|
||||
// If the password is still the MD5 of the old password, then it hasnt changed
|
||||
if (($old=Arr::get($o->userpassword,$key)) && ($value === md5($old))) {
|
||||
array_push($passwords,$old);
|
||||
if (($old=Arr::get($po,$dotkey)) && ($value === md5($old))) {
|
||||
$passwords[$dotkey] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value) {
|
||||
$type = Arr::get($request->userpassword_hash,$key);
|
||||
array_push($passwords,Password::hash_id($type)->encode($value));
|
||||
$type = Arr::get($request->userpassword_hash,$dotkey);
|
||||
$passwords[$dotkey] = Password::hash_id($type)
|
||||
->encode($value);
|
||||
}
|
||||
}
|
||||
$o->userpassword = $passwords;
|
||||
|
||||
$o->userpassword = Arr::undot($passwords);
|
||||
}
|
||||
|
||||
if (! $o->getDirty())
|
||||
@ -347,7 +351,7 @@ class HomeController extends Controller
|
||||
|
||||
return Redirect::to('/')
|
||||
->withInput()
|
||||
->with('updated',collect($dirty)->map(fn($key,$item)=>$o->getObject($item)));
|
||||
->with('updated',collect($dirty)->map(fn($item,$key)=>$o->getObject(collect(explode(';',$key))->first())));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -372,11 +376,12 @@ class HomeController extends Controller
|
||||
->with('bases',$this->bases());
|
||||
|
||||
// If we are rendering a DN, rebuild our object
|
||||
$o = config('server')->fetch($key['dn']);
|
||||
if ($key['dn']) {
|
||||
$o = config('server')->fetch($key['dn']);
|
||||
|
||||
// @todo We need to dynamically exclude request items, so we dont need to add them here
|
||||
foreach (collect(old())->except(['dn','_token','userpassword_hash']) as $attr => $value)
|
||||
$o->{$attr} = $value;
|
||||
foreach (collect(old())->except(['key','dn','step','_token','userpassword_hash']) as $attr => $value)
|
||||
$o->{$attr} = $value;
|
||||
}
|
||||
|
||||
return match ($key['cmd']) {
|
||||
'create' => $view
|
||||
@ -386,7 +391,13 @@ class HomeController extends Controller
|
||||
'dn' => $view
|
||||
->with('dn',$key['dn'])
|
||||
->with('o',$o)
|
||||
->with('page_actions',collect(['edit'=>TRUE])),
|
||||
->with('page_actions',collect([
|
||||
'copy'=>FALSE,
|
||||
'create'=>FALSE,
|
||||
'delete'=>TRUE,
|
||||
'edit'=>TRUE,
|
||||
'export'=>TRUE,
|
||||
])),
|
||||
|
||||
'import' => $view,
|
||||
|
||||
|
@ -34,10 +34,11 @@ class EntryAddRequest extends FormRequest
|
||||
if (request()->method() === 'GET')
|
||||
return [];
|
||||
|
||||
$r = request() ?: collect();
|
||||
return config('server')
|
||||
->schema('attributetypes')
|
||||
->intersectByKeys($this->request)
|
||||
->map(fn($item)=>$item->validation(request()->get('objectclass')))
|
||||
->intersectByKeys($r->all())
|
||||
->map(fn($item)=>$item->validation($r->get('objectclass',[])))
|
||||
->filter()
|
||||
->flatMap(fn($item)=>$item)
|
||||
->merge([
|
||||
@ -60,6 +61,12 @@ class EntryAddRequest extends FormRequest
|
||||
'rdn_value' => 'required_if:step,2|string|min:1',
|
||||
'step' => 'int|min:1|max:2',
|
||||
'objectclass'=>[
|
||||
'required',
|
||||
'array',
|
||||
'min:1',
|
||||
'max:1',
|
||||
],
|
||||
'objectclass._null_'=>[
|
||||
'required',
|
||||
'array',
|
||||
'min:1',
|
||||
|
@ -13,10 +13,12 @@ class EntryRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$r = request() ?: collect();
|
||||
|
||||
return config('server')
|
||||
->schema('attributetypes')
|
||||
->intersectByKeys($this->request)
|
||||
->map(fn($item)=>$item->validation(request()?->get('objectclass') ?: []))
|
||||
->intersectByKeys($r->all())
|
||||
->map(fn($item)=>$item->validation($r->get('objectclass',[])))
|
||||
->filter()
|
||||
->flatMap(fn($item)=>$item)
|
||||
->toArray();
|
||||
|
@ -14,8 +14,17 @@ use App\Classes\LDAP\Export\LDIF;
|
||||
use App\Exceptions\Import\AttributeException;
|
||||
use App\Exceptions\InvalidUsage;
|
||||
|
||||
/**
|
||||
* An Entry in an LDAP server
|
||||
*
|
||||
* @notes https://ldap.com/ldap-dns-and-rdns
|
||||
*/
|
||||
class Entry extends Model
|
||||
{
|
||||
private const TAG_CHARS = 'a-zA-Z0-9-';
|
||||
private const TAG_CHARS_LANG = 'lang-['.self::TAG_CHARS.']';
|
||||
public const TAG_NOTAG = '_null_';
|
||||
|
||||
// Our Attribute objects
|
||||
private Collection $objects;
|
||||
/* @deprecated */
|
||||
@ -45,13 +54,18 @@ class Entry extends Model
|
||||
/**
|
||||
* This function overrides getAttributes to use our collection of Attribute objects instead of the models attributes.
|
||||
*
|
||||
* This returns an array that should be consistent with $this->attributes
|
||||
*
|
||||
* @return array
|
||||
* @note $this->attributes may not be updated with changes
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->objects
|
||||
->map(fn($item)=>$item->values)
|
||||
->flatMap(fn($item)=>
|
||||
($item->no_attr_tags)
|
||||
? [strtolower($item->name)=>$item->values]
|
||||
: $item->values
|
||||
->flatMap(fn($v,$k)=>[strtolower($item->name.($k !== self::TAG_NOTAG ? ';'.$k : ''))=>$v]))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -64,12 +78,10 @@ class Entry extends Model
|
||||
{
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
|
||||
// @todo Silently ignore keys of language tags - we should work with them
|
||||
if (str_contains($key,';'))
|
||||
return TRUE;
|
||||
list($attribute,$tag) = $this->keytag($key);
|
||||
|
||||
return ((! array_key_exists($key,$this->original)) && (! $this->objects->has($key)))
|
||||
|| (! $this->getObject($key)->isDirty());
|
||||
return ((! array_key_exists($key,$this->original)) && (! $this->objects->has($attribute)))
|
||||
|| (! $this->getObject($attribute)->isDirty());
|
||||
}
|
||||
|
||||
public static function query(bool $noattrs=false): Builder
|
||||
@ -86,18 +98,22 @@ class Entry extends Model
|
||||
* As attribute values are updated, or new ones created, we need to mirror that
|
||||
* into our $objects. This is called when we $o->key = $value
|
||||
*
|
||||
* This function should update $this->attributes and correctly reflect changes in $this->objects
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute(string $key,mixed $value): static
|
||||
{
|
||||
parent::setAttribute($key,$value);
|
||||
foreach ($value as $k => $v)
|
||||
parent::setAttribute($key.($k !== self::TAG_NOTAG ? ';'.$k : ''),$v);
|
||||
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
list($attribute,$tags) = $this->keytag($key);
|
||||
|
||||
$o = $this->objects->get($key) ?: Factory::create($this->dn ?: '',$key,[],Arr::get($this->attributes,'objectclass',[]));
|
||||
$o->values = collect($this->attributes[$key]);
|
||||
$o = $this->objects->get($attribute) ?: Factory::create($this->dn ?: '',$attribute,[],Arr::get($this->attributes,'objectclass',[]));
|
||||
$o->values = collect($value);
|
||||
|
||||
$this->objects->put($key,$o);
|
||||
|
||||
@ -158,15 +174,48 @@ class Entry extends Model
|
||||
if (! is_string($value))
|
||||
throw new \Exception('value should be a string');
|
||||
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
$key = $this->normalizeAttributeKey(strtolower($key));
|
||||
|
||||
if (! config('server')->schema('attributetypes')->has($key))
|
||||
throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$key));
|
||||
// If the attribute name has tags
|
||||
list($attribute,$tag) = $this->keytag($key);
|
||||
|
||||
$o = $this->objects->get($key) ?: Attribute\Factory::create($this->dn ?: '',$key,[]);
|
||||
$o->addValue($value);
|
||||
if (! config('server')->schema('attributetypes')->has($attribute))
|
||||
throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$attribute));
|
||||
|
||||
$this->objects->put($key,$o);
|
||||
$o = $this->objects->get($attribute) ?: Attribute\Factory::create($this->dn ?: '',$attribute,[]);
|
||||
$o->addValue($tag,[$value]);
|
||||
|
||||
$this->objects->put($attribute,$o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this record
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $scope
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function export(string $method,string $scope): string
|
||||
{
|
||||
// @todo To implement
|
||||
switch ($scope) {
|
||||
case 'base':
|
||||
case 'one':
|
||||
case 'sub':
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('Export scope unknown:'.$scope);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'ldif':
|
||||
return new LDIF(collect($this));
|
||||
|
||||
default:
|
||||
throw new \Exception('Export method not implemented:'.$method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,34 +228,26 @@ class Entry extends Model
|
||||
$result = collect();
|
||||
$entry_oc = Arr::get($this->attributes,'objectclass',[]);
|
||||
|
||||
foreach ($this->attributes as $attribute => $values) {
|
||||
// If the attribute name has tags
|
||||
$matches = [];
|
||||
if (preg_match('/^([a-zA-Z]+)(;([a-zA-Z-;]+))+/',$attribute,$matches)) {
|
||||
$attribute = $matches[1];
|
||||
foreach ($this->attributes as $attrtag => $values) {
|
||||
list($attribute,$tags) = $this->keytag($attrtag);
|
||||
|
||||
// If the attribute doesnt exist we'll create it
|
||||
$o = Arr::get(
|
||||
$result,
|
||||
$orig = Arr::get($this->original,$attrtag,[]);
|
||||
|
||||
// If the attribute doesnt exist we'll create it
|
||||
$o = Arr::get(
|
||||
$result,
|
||||
$attribute,
|
||||
Factory::create(
|
||||
$this->dn,
|
||||
$attribute,
|
||||
Factory::create(
|
||||
$this->dn,
|
||||
$attribute,
|
||||
Arr::get($this->original,$attribute,[]),
|
||||
$entry_oc,
|
||||
));
|
||||
$o->setLangTag($matches[3],$values);
|
||||
[$tags=>$orig],
|
||||
$entry_oc,
|
||||
));
|
||||
|
||||
} else {
|
||||
$o = Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),$entry_oc);
|
||||
}
|
||||
$o->addValue($tags,$values);
|
||||
$o->addValueOld($tags,Arr::get($this->original,$attrtag));
|
||||
|
||||
if (! $result->has($attribute)) {
|
||||
// Store our new values to know if this attribute has changed
|
||||
$o->values = collect($values);
|
||||
|
||||
$result->put($attribute,$o);
|
||||
}
|
||||
$result->put($attribute,$o);
|
||||
}
|
||||
|
||||
$sort = collect(config('pla.attr_display_order',[]))->map(fn($item)=>strtolower($item));
|
||||
@ -247,7 +288,7 @@ class Entry extends Model
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
foreach ($this->objectclass as $oc)
|
||||
foreach ($this->getObject('objectclass')->values as $oc)
|
||||
$result = $result->merge(config('server')->schema('objectclasses',$oc)->attributes);
|
||||
|
||||
return $result;
|
||||
@ -274,6 +315,38 @@ class Entry extends Model
|
||||
->filter(fn($item)=>$item->is_internal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify the language tags (RFC 3866) used by this entry
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getLangTags(): Collection
|
||||
{
|
||||
return $this->getObjects()
|
||||
->filter(fn($item)=>! $item->no_attr_tags)
|
||||
->map(fn($item)=>$item
|
||||
->values
|
||||
->keys()
|
||||
->filter(fn($item)=>preg_match(sprintf('/%s+;?/',self::TAG_CHARS_LANG),$item))
|
||||
->map(fn($item)=>preg_replace('/lang-/','',$item))
|
||||
)
|
||||
->filter(fn($item)=>$item->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Of all the items with lang tags, which ones have more than 1 lang tag
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getLangMultiTags(): Collection
|
||||
{
|
||||
return $this->getLangTags()
|
||||
->map(fn($item)=>$item->values()
|
||||
->map(fn($item)=>explode(';',$item))
|
||||
->filter(fn($item)=>count($item) > 1))
|
||||
->filter(fn($item)=>$item->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an attribute as an object
|
||||
*
|
||||
@ -299,10 +372,36 @@ class Entry extends Model
|
||||
return $this->objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find other attribute tags used by this entry
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getOtherTags(): Collection
|
||||
{
|
||||
return $this->getObjects()
|
||||
->filter(fn($item)=>! $item->no_attr_tags)
|
||||
->map(fn($item)=>$item
|
||||
->values
|
||||
->keys()
|
||||
->filter(fn($item)=>
|
||||
$item && collect(explode(';',$item))->filter(
|
||||
fn($item)=>
|
||||
(! preg_match(sprintf('/^%s$/',self::TAG_NOTAG),$item))
|
||||
&& (! preg_match(sprintf('/^%s+$/',self::TAG_CHARS_LANG),$item))
|
||||
)
|
||||
->count())
|
||||
)
|
||||
->filter(fn($item)=>$item->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of attributes without any values
|
||||
*
|
||||
* @return Collection
|
||||
* @todo Dont show attributes that are not provided by an objectclass, make a new function to show those
|
||||
* This is for dynamic list items eg: labeledURI, which are not editable.
|
||||
* We can highlight those values that are as a result of a dynamic module
|
||||
*/
|
||||
public function getMissingAttributes(): Collection
|
||||
{
|
||||
@ -323,12 +422,22 @@ class Entry extends Model
|
||||
/**
|
||||
* Return this list of user attributes
|
||||
*
|
||||
* @param string $tag If null return all tags
|
||||
* @return Collection
|
||||
*/
|
||||
public function getVisibleAttributes(): Collection
|
||||
public function getVisibleAttributes(string $tag=''): Collection
|
||||
{
|
||||
return $this->objects
|
||||
->filter(fn($item)=>! $item->is_internal);
|
||||
static $cache = [];
|
||||
|
||||
if (! Arr::get($cache,$tag ?: '_all_')) {
|
||||
$ot = $this->getOtherTags();
|
||||
|
||||
$cache[$tag ?: '_all_'] = $this->objects
|
||||
->filter(fn($item)=>(! $item->is_internal) && ((! $item->no_attr_tags) || (! $tag) || ($tag === Entry::TAG_NOTAG)))
|
||||
->filter(fn($item)=>(! $tag) || $ot->has($item->name_lc) || count($item->tagValues($tag)) > 0);
|
||||
}
|
||||
|
||||
return $cache[$tag ?: '_all_'];
|
||||
}
|
||||
|
||||
public function hasAttribute(int|string $key): bool
|
||||
@ -337,36 +446,6 @@ class Entry extends Model
|
||||
->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this record
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $scope
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function export(string $method,string $scope): string
|
||||
{
|
||||
// @todo To implement
|
||||
switch ($scope) {
|
||||
case 'base':
|
||||
case 'one':
|
||||
case 'sub':
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('Export scope unknown:'.$scope);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'ldif':
|
||||
return new LDIF(collect($this));
|
||||
|
||||
default:
|
||||
throw new \Exception('Export method not implemented:'.$method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an icon for a DN based on objectClass
|
||||
*
|
||||
@ -374,65 +453,92 @@ class Entry extends Model
|
||||
*/
|
||||
public function icon(): string
|
||||
{
|
||||
$objectclasses = array_map('strtolower',$this->objectclass);
|
||||
$objectclasses = $this->getObject('objectclass')
|
||||
->tagValues()
|
||||
->map(fn($item)=>strtolower($item));
|
||||
|
||||
// Return icon based upon objectClass value
|
||||
if (in_array('person',$objectclasses) ||
|
||||
in_array('organizationalperson',$objectclasses) ||
|
||||
in_array('inetorgperson',$objectclasses) ||
|
||||
in_array('account',$objectclasses) ||
|
||||
in_array('posixaccount',$objectclasses))
|
||||
|
||||
if ($objectclasses->intersect([
|
||||
'account',
|
||||
'inetorgperson',
|
||||
'organizationalperson',
|
||||
'person',
|
||||
'posixaccount',
|
||||
])->count())
|
||||
return 'fas fa-user';
|
||||
|
||||
elseif (in_array('organization',$objectclasses))
|
||||
elseif ($objectclasses->contains('organization'))
|
||||
return 'fas fa-university';
|
||||
|
||||
elseif (in_array('organizationalunit',$objectclasses))
|
||||
elseif ($objectclasses->contains('organizationalunit'))
|
||||
return 'fas fa-object-group';
|
||||
|
||||
elseif (in_array('posixgroup',$objectclasses) ||
|
||||
in_array('groupofnames',$objectclasses) ||
|
||||
in_array('groupofuniquenames',$objectclasses) ||
|
||||
in_array('group',$objectclasses))
|
||||
|
||||
elseif ($objectclasses->intersect([
|
||||
'posixgroup',
|
||||
'groupofnames',
|
||||
'groupofuniquenames',
|
||||
'group',
|
||||
])->count())
|
||||
return 'fas fa-users';
|
||||
|
||||
elseif (in_array('dcobject',$objectclasses) ||
|
||||
in_array('domainrelatedobject',$objectclasses) ||
|
||||
in_array('domain',$objectclasses) ||
|
||||
in_array('builtindomain',$objectclasses))
|
||||
|
||||
elseif ($objectclasses->intersect([
|
||||
'dcobject',
|
||||
'domainrelatedobject',
|
||||
'domain',
|
||||
'builtindomain',
|
||||
])->count())
|
||||
return 'fas fa-network-wired';
|
||||
|
||||
elseif (in_array('alias',$objectclasses))
|
||||
elseif ($objectclasses->contains('alias'))
|
||||
return 'fas fa-theater-masks';
|
||||
|
||||
elseif (in_array('country',$objectclasses))
|
||||
return sprintf('flag %s',strtolower(Arr::get($this->c,0)));
|
||||
elseif ($objectclasses->contains('country'))
|
||||
return sprintf('flag %s',strtolower(Arr::get($this->c ?: [],0)));
|
||||
|
||||
elseif (in_array('device',$objectclasses))
|
||||
elseif ($objectclasses->contains('device'))
|
||||
return 'fas fa-mobile-alt';
|
||||
|
||||
elseif (in_array('document',$objectclasses))
|
||||
elseif ($objectclasses->contains('document'))
|
||||
return 'fas fa-file-alt';
|
||||
|
||||
elseif (in_array('iphost',$objectclasses))
|
||||
elseif ($objectclasses->contains('iphost'))
|
||||
return 'fas fa-wifi';
|
||||
|
||||
elseif (in_array('room',$objectclasses))
|
||||
elseif ($objectclasses->contains('room'))
|
||||
return 'fas fa-door-open';
|
||||
|
||||
elseif (in_array('server',$objectclasses))
|
||||
elseif ($objectclasses->contains('server'))
|
||||
return 'fas fa-server';
|
||||
|
||||
elseif (in_array('openldaprootdse',$objectclasses))
|
||||
elseif ($objectclasses->contains('openldaprootdse'))
|
||||
return 'fas fa-info';
|
||||
|
||||
// Default
|
||||
return 'fa-fw fas fa-cog';
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an LDAP attribute, this will return the attribute name and the tag
|
||||
* eg: description;lang-cn will return [description,lang-cn]
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
private function keytag(string $key): array
|
||||
{
|
||||
$matches = [];
|
||||
if (preg_match(sprintf('/^([%s]+);+([%s;]+)/',self::TAG_CHARS,self::TAG_CHARS),$key,$matches)) {
|
||||
$attribute = $matches[1];
|
||||
$tags = $matches[2];
|
||||
|
||||
} else {
|
||||
$attribute = $key;
|
||||
$tags = self::TAG_NOTAG;
|
||||
}
|
||||
|
||||
return [$attribute,$tags];
|
||||
}
|
||||
|
||||
/**
|
||||
* Dont convert our $this->attributes to $this->objects when creating a new Entry::class
|
||||
*
|
||||
|
@ -20,7 +20,7 @@ class HasStructuralObjectClass implements ValidationRule
|
||||
*/
|
||||
public function validate(string $attribute,mixed $value,Closure $fail): void
|
||||
{
|
||||
foreach ($value as $item)
|
||||
foreach (collect($value)->dot() as $item)
|
||||
if ($item && config('server')->schema('objectclasses',$item)->isStructural())
|
||||
return;
|
||||
|
||||
|
@ -11,8 +11,8 @@ trait MD5Updates
|
||||
{
|
||||
public function isDirty(): bool
|
||||
{
|
||||
foreach ($this->values->diff($this->values_old) as $key => $value)
|
||||
if (md5(Arr::get($this->values_old,$key)) !== $value)
|
||||
foreach ($this->values_old->dot()->keys()->merge($this->values->dot()->keys())->unique() as $dotkey)
|
||||
if (md5(Arr::get($this->values_old->dot(),$dotkey)) !== Arr::get($this->values->dot(),$dotkey))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
@ -2,9 +2,12 @@
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
use App\Classes\LDAP\Attribute as LDAPAttribute;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
class Attribute extends Component
|
||||
{
|
||||
@ -12,30 +15,32 @@ class Attribute extends Component
|
||||
public bool $edit;
|
||||
public bool $new;
|
||||
public bool $old;
|
||||
public ?string $na;
|
||||
public string $langtag;
|
||||
public ?string $na; // Text to render if the LDAPAttribute is null
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,?string $na=NULL)
|
||||
{
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,?string $na=NULL)
|
||||
{
|
||||
$this->o = $o;
|
||||
$this->edit = $edit;
|
||||
$this->old = $old;
|
||||
$this->new = $new;
|
||||
$this->langtag = $langtag;
|
||||
$this->na = $na;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return View|string
|
||||
*/
|
||||
public function render(): View|string
|
||||
{
|
||||
return $this->o
|
||||
? $this->o
|
||||
->render($this->edit,$this->old,$this->new)
|
||||
->render(edit: $this->edit,old: $this->old,new: $this->new)
|
||||
: $this->na;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,34 +2,39 @@
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
use App\Classes\LDAP\Attribute as LDAPAttribute;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
class AttributeType extends Component
|
||||
{
|
||||
private LDAPAttribute $o;
|
||||
private bool $new;
|
||||
private bool $edit;
|
||||
private string $langtag;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(LDAPAttribute $o,bool $new=FALSE)
|
||||
public function __construct(LDAPAttribute $o,bool $new=FALSE,bool $edit=FALSE,string $langtag=Entry::TAG_NOTAG)
|
||||
{
|
||||
$this->o = $o;
|
||||
$this->new = $new;
|
||||
$this->edit = $edit;
|
||||
$this->langtag = $langtag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
public function render(): View
|
||||
{
|
||||
return view('components.attribute-type')
|
||||
->with('o',$this->o)
|
||||
->with('new',$this->new);
|
||||
->with('new',$this->new)
|
||||
->with('edit',$this->edit)
|
||||
->with('langtag',$this->langtag);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"ext-ldap": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": "^8.4",
|
||||
"directorytree/ldaprecord-laravel": "^3.0",
|
||||
"laravel/framework": "^11.9",
|
||||
|
283
composer.lock
generated
283
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2f0a146742112814f55f6a4e5bd12da3",
|
||||
"content-hash": "ddfbe582d0c27ef08ff1410102ccda28",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -288,16 +288,16 @@
|
||||
},
|
||||
{
|
||||
"name": "directorytree/ldaprecord-laravel",
|
||||
"version": "v3.4.0",
|
||||
"version": "v3.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DirectoryTree/LdapRecord-Laravel.git",
|
||||
"reference": "bb0aa206723ed07e2b42eadd7311d5949cc770dd"
|
||||
"reference": "15f56e01319852d41023633d3688ac4aa139aa6e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/DirectoryTree/LdapRecord-Laravel/zipball/bb0aa206723ed07e2b42eadd7311d5949cc770dd",
|
||||
"reference": "bb0aa206723ed07e2b42eadd7311d5949cc770dd",
|
||||
"url": "https://api.github.com/repos/DirectoryTree/LdapRecord-Laravel/zipball/15f56e01319852d41023633d3688ac4aa139aa6e",
|
||||
"reference": "15f56e01319852d41023633d3688ac4aa139aa6e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -343,7 +343,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/DirectoryTree/LdapRecord-Laravel/issues",
|
||||
"source": "https://github.com/DirectoryTree/LdapRecord-Laravel/tree/v3.4.0"
|
||||
"source": "https://github.com/DirectoryTree/LdapRecord-Laravel/tree/v3.4.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -351,7 +351,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-26T01:41:53+00:00"
|
||||
"time": "2025-03-21T19:16:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
@ -588,16 +588,16 @@
|
||||
},
|
||||
{
|
||||
"name": "egulias/email-validator",
|
||||
"version": "4.0.3",
|
||||
"version": "4.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/egulias/EmailValidator.git",
|
||||
"reference": "b115554301161fa21467629f1e1391c1936de517"
|
||||
"reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517",
|
||||
"reference": "b115554301161fa21467629f1e1391c1936de517",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa",
|
||||
"reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -643,7 +643,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/egulias/EmailValidator/issues",
|
||||
"source": "https://github.com/egulias/EmailValidator/tree/4.0.3"
|
||||
"source": "https://github.com/egulias/EmailValidator/tree/4.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -651,7 +651,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-27T00:36:43+00:00"
|
||||
"time": "2025-03-06T22:45:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fruitcake/php-cors",
|
||||
@ -788,16 +788,16 @@
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.9.2",
|
||||
"version": "7.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "d281ed313b989f213357e3be1a179f02196ac99b"
|
||||
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b",
|
||||
"reference": "d281ed313b989f213357e3be1a179f02196ac99b",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
|
||||
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -894,7 +894,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.9.2"
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -910,20 +910,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-24T11:22:20+00:00"
|
||||
"time": "2025-03-27T13:37:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "2.0.4",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/promises.git",
|
||||
"reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455"
|
||||
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
|
||||
"reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
|
||||
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -977,7 +977,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/promises/issues",
|
||||
"source": "https://github.com/guzzle/promises/tree/2.0.4"
|
||||
"source": "https://github.com/guzzle/promises/tree/2.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -993,20 +993,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-17T10:06:22+00:00"
|
||||
"time": "2025-03-27T13:27:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "2.7.0",
|
||||
"version": "2.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201"
|
||||
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
|
||||
"reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
|
||||
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1093,7 +1093,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/psr7/issues",
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.7.0"
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1109,7 +1109,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-18T11:15:46+00:00"
|
||||
"time": "2025-03-27T12:30:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/uri-template",
|
||||
@ -1537,16 +1537,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v2.0.3",
|
||||
"version": "v2.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/serializable-closure.git",
|
||||
"reference": "f379c13663245f7aa4512a7869f62eb14095f23f"
|
||||
"reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f379c13663245f7aa4512a7869f62eb14095f23f",
|
||||
"reference": "f379c13663245f7aa4512a7869f62eb14095f23f",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b352cf0534aa1ae6b4d825d1e762e35d43f8a841",
|
||||
"reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1594,7 +1594,7 @@
|
||||
"issues": "https://github.com/laravel/serializable-closure/issues",
|
||||
"source": "https://github.com/laravel/serializable-closure"
|
||||
},
|
||||
"time": "2025-02-11T15:03:05+00:00"
|
||||
"time": "2025-03-19T13:51:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/ui",
|
||||
@ -2212,16 +2212,16 @@
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.8.1",
|
||||
"version": "3.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4"
|
||||
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4",
|
||||
"reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
|
||||
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2299,7 +2299,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Seldaek/monolog/issues",
|
||||
"source": "https://github.com/Seldaek/monolog/tree/3.8.1"
|
||||
"source": "https://github.com/Seldaek/monolog/tree/3.9.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2311,20 +2311,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-05T17:15:07+00:00"
|
||||
"time": "2025-03-24T10:02:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.8.6",
|
||||
"version": "3.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||
"reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd"
|
||||
"reference": "6d16a8a015166fe54e22c042e0805c5363aef50d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
|
||||
"reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/6d16a8a015166fe54e22c042e0805c5363aef50d",
|
||||
"reference": "6d16a8a015166fe54e22c042e0805c5363aef50d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2417,7 +2417,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-20T17:33:38+00:00"
|
||||
"time": "2025-03-27T12:57:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
@ -2483,16 +2483,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nette/utils",
|
||||
"version": "v4.0.5",
|
||||
"version": "v4.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/utils.git",
|
||||
"reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96"
|
||||
"reference": "ce708655043c7050eb050df361c5e313cf708309"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
|
||||
"reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
|
||||
"url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309",
|
||||
"reference": "ce708655043c7050eb050df361c5e313cf708309",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2563,9 +2563,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/utils/issues",
|
||||
"source": "https://github.com/nette/utils/tree/v4.0.5"
|
||||
"source": "https://github.com/nette/utils/tree/v4.0.6"
|
||||
},
|
||||
"time": "2024-08-07T15:39:19+00:00"
|
||||
"time": "2025-03-30T21:06:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/termwind",
|
||||
@ -3187,16 +3187,16 @@
|
||||
},
|
||||
{
|
||||
"name": "ramsey/collection",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/collection.git",
|
||||
"reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109"
|
||||
"reference": "344572933ad0181accbf4ba763e85a0306a8c5e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/collection/zipball/3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109",
|
||||
"reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109",
|
||||
"url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2",
|
||||
"reference": "344572933ad0181accbf4ba763e85a0306a8c5e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3257,9 +3257,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/collection/issues",
|
||||
"source": "https://github.com/ramsey/collection/tree/2.1.0"
|
||||
"source": "https://github.com/ramsey/collection/tree/2.1.1"
|
||||
},
|
||||
"time": "2025-03-02T04:48:29+00:00"
|
||||
"time": "2025-03-22T05:38:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
@ -3429,16 +3429,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.2.1",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3"
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3502,7 +3502,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.1"
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3518,7 +3518,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-11T03:49:26+00:00"
|
||||
"time": "2025-03-12T08:11:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
@ -3654,16 +3654,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/error-handler",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/error-handler.git",
|
||||
"reference": "aabf79938aa795350c07ce6464dd1985607d95d5"
|
||||
"reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/aabf79938aa795350c07ce6464dd1985607d95d5",
|
||||
"reference": "aabf79938aa795350c07ce6464dd1985607d95d5",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b",
|
||||
"reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3709,7 +3709,7 @@
|
||||
"description": "Provides tools to manage errors and ease debugging PHP code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/error-handler/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/error-handler/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3725,7 +3725,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-02T20:27:07+00:00"
|
||||
"time": "2025-03-03T07:12:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
@ -3949,16 +3949,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v7.2.3",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0"
|
||||
"reference": "371272aeb6286f8135e028ca535f8e4d6f114126"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/ee1b504b8926198be89d05e5b6fc4c3810c090f0",
|
||||
"reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/371272aeb6286f8135e028ca535f8e4d6f114126",
|
||||
"reference": "371272aeb6286f8135e028ca535f8e4d6f114126",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4007,7 +4007,7 @@
|
||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.2.3"
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4023,20 +4023,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-17T10:56:55+00:00"
|
||||
"time": "2025-03-25T15:54:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "9f1103734c5789798fefb90e91de4586039003ed"
|
||||
"reference": "b1fe91bc1fa454a806d3f98db4ba826eb9941a54"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/9f1103734c5789798fefb90e91de4586039003ed",
|
||||
"reference": "9f1103734c5789798fefb90e91de4586039003ed",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/b1fe91bc1fa454a806d3f98db4ba826eb9941a54",
|
||||
"reference": "b1fe91bc1fa454a806d3f98db4ba826eb9941a54",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4121,7 +4121,7 @@
|
||||
"description": "Provides a structured process for converting a Request into a Response",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4137,7 +4137,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-26T11:01:22+00:00"
|
||||
"time": "2025-03-28T13:32:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailer",
|
||||
@ -4941,16 +4941,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf"
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf",
|
||||
"reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4982,7 +4982,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4998,7 +4998,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-05T08:33:46+00:00"
|
||||
"time": "2025-03-13T12:21:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
@ -5856,16 +5856,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "barryvdh/laravel-debugbar",
|
||||
"version": "v3.15.2",
|
||||
"version": "v3.15.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||
"reference": "0bc1e1361e7fffc2be156f46ad1fba6927c01729"
|
||||
"reference": "4ccab20844d18c5af08b68d310e7151a791c3037"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/0bc1e1361e7fffc2be156f46ad1fba6927c01729",
|
||||
"reference": "0bc1e1361e7fffc2be156f46ad1fba6927c01729",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/4ccab20844d18c5af08b68d310e7151a791c3037",
|
||||
"reference": "4ccab20844d18c5af08b68d310e7151a791c3037",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5876,9 +5876,6 @@
|
||||
"php-debugbar/php-debugbar": "~2.1.1",
|
||||
"symfony/finder": "^6|^7"
|
||||
},
|
||||
"conflict": {
|
||||
"maximebf/debugbar": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.3.3",
|
||||
"orchestra/testbench-dusk": "^7|^8|^9|^10",
|
||||
@ -5928,7 +5925,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
|
||||
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.15.2"
|
||||
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.15.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -5940,7 +5937,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-25T15:25:22+00:00"
|
||||
"time": "2025-04-08T15:11:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
@ -6007,16 +6004,16 @@
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.17.0",
|
||||
"version": "2.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "075bc0c26631110584175de6523ab3f1652eb28e"
|
||||
"reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/075bc0c26631110584175de6523ab3f1652eb28e",
|
||||
"reference": "075bc0c26631110584175de6523ab3f1652eb28e",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e",
|
||||
"reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6066,7 +6063,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/filp/whoops/issues",
|
||||
"source": "https://github.com/filp/whoops/tree/2.17.0"
|
||||
"source": "https://github.com/filp/whoops/tree/2.18.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -6074,7 +6071,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-25T12:00:00+00:00"
|
||||
"time": "2025-03-15T12:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
@ -6330,38 +6327,39 @@
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v8.6.1",
|
||||
"version": "v8.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/collision.git",
|
||||
"reference": "86f003c132143d5a2ab214e19933946409e0cae7"
|
||||
"reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/86f003c132143d5a2ab214e19933946409e0cae7",
|
||||
"reference": "86f003c132143d5a2ab214e19933946409e0cae7",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/4cf9f3b47afff38b139fb79ce54fc71799022ce8",
|
||||
"reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"filp/whoops": "^2.16.0",
|
||||
"filp/whoops": "^2.18.0",
|
||||
"nunomaduro/termwind": "^2.3.0",
|
||||
"php": "^8.2.0",
|
||||
"symfony/console": "^7.2.1"
|
||||
"symfony/console": "^7.2.5"
|
||||
},
|
||||
"conflict": {
|
||||
"laravel/framework": "<11.39.1 || >=13.0.0",
|
||||
"phpunit/phpunit": "<11.5.3 || >=12.0.0"
|
||||
"laravel/framework": "<11.44.2 || >=13.0.0",
|
||||
"phpunit/phpunit": "<11.5.15 || >=13.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"larastan/larastan": "^2.9.12",
|
||||
"laravel/framework": "^11.39.1",
|
||||
"laravel/pint": "^1.20.0",
|
||||
"laravel/sail": "^1.40.0",
|
||||
"laravel/sanctum": "^4.0.7",
|
||||
"laravel/tinker": "^2.10.0",
|
||||
"orchestra/testbench-core": "^9.9.2",
|
||||
"pestphp/pest": "^3.7.3",
|
||||
"sebastian/environment": "^6.1.0 || ^7.2.0"
|
||||
"brianium/paratest": "^7.8.3",
|
||||
"larastan/larastan": "^3.2",
|
||||
"laravel/framework": "^11.44.2 || ^12.6",
|
||||
"laravel/pint": "^1.21.2",
|
||||
"laravel/sail": "^1.41.0",
|
||||
"laravel/sanctum": "^4.0.8",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"orchestra/testbench-core": "^9.12.0 || ^10.1",
|
||||
"pestphp/pest": "^3.8.0",
|
||||
"sebastian/environment": "^7.2.0 || ^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@ -6424,7 +6422,7 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-23T13:41:43+00:00"
|
||||
"time": "2025-04-03T14:33:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@ -6939,16 +6937,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "11.5.12",
|
||||
"version": "11.5.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "d42785840519401ed2113292263795eb4c0f95da"
|
||||
"reference": "fd2e863a2995cdfd864fb514b5e0b28b09895b5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d42785840519401ed2113292263795eb4c0f95da",
|
||||
"reference": "d42785840519401ed2113292263795eb4c0f95da",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fd2e863a2995cdfd864fb514b5e0b28b09895b5c",
|
||||
"reference": "fd2e863a2995cdfd864fb514b5e0b28b09895b5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6968,14 +6966,14 @@
|
||||
"phpunit/php-text-template": "^4.0.1",
|
||||
"phpunit/php-timer": "^7.0.1",
|
||||
"sebastian/cli-parser": "^3.0.2",
|
||||
"sebastian/code-unit": "^3.0.2",
|
||||
"sebastian/code-unit": "^3.0.3",
|
||||
"sebastian/comparator": "^6.3.1",
|
||||
"sebastian/diff": "^6.0.2",
|
||||
"sebastian/environment": "^7.2.0",
|
||||
"sebastian/exporter": "^6.3.0",
|
||||
"sebastian/global-state": "^7.0.2",
|
||||
"sebastian/object-enumerator": "^6.0.1",
|
||||
"sebastian/type": "^5.1.0",
|
||||
"sebastian/type": "^5.1.2",
|
||||
"sebastian/version": "^5.0.2",
|
||||
"staabm/side-effects-detector": "^1.0.5"
|
||||
},
|
||||
@ -7020,7 +7018,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.12"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.17"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -7036,7 +7034,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-07T07:31:03+00:00"
|
||||
"time": "2025-04-08T07:59:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@ -7097,16 +7095,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit",
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/code-unit.git",
|
||||
"reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca"
|
||||
"reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca",
|
||||
"reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64",
|
||||
"reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7142,7 +7140,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/code-unit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/code-unit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2"
|
||||
"source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -7150,7 +7148,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-12T09:59:06+00:00"
|
||||
"time": "2025-03-19T07:56:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
@ -7855,16 +7853,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/type",
|
||||
"version": "5.1.0",
|
||||
"version": "5.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/type.git",
|
||||
"reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac"
|
||||
"reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac",
|
||||
"reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e",
|
||||
"reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7900,7 +7898,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/type/issues",
|
||||
"security": "https://github.com/sebastianbergmann/type/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/5.1.0"
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/5.1.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -7908,7 +7906,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-17T13:12:04+00:00"
|
||||
"time": "2025-03-18T13:35:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
@ -8455,6 +8453,7 @@
|
||||
"platform": {
|
||||
"ext-fileinfo": "*",
|
||||
"ext-ldap": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": "^8.4"
|
||||
},
|
||||
"platform-dev": {},
|
||||
|
@ -122,47 +122,47 @@ return [
|
||||
*/
|
||||
'validation' => [
|
||||
'objectclass' => [
|
||||
'objectclass'=>[
|
||||
'objectclass.*'=>[
|
||||
new HasStructuralObjectClass,
|
||||
]
|
||||
],
|
||||
'gidnumber' => [
|
||||
'gidnumber'=> [
|
||||
'gidnumber.*'=> [
|
||||
'sometimes',
|
||||
'max:1'
|
||||
],
|
||||
'gidnumber.*' => [
|
||||
'gidnumber.*.*' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
'max:65535'
|
||||
]
|
||||
],
|
||||
'mail' => [
|
||||
'mail'=>[
|
||||
'mail.*'=>[
|
||||
'sometimes',
|
||||
'min:1'
|
||||
],
|
||||
'mail.*' => [
|
||||
'mail.*.*' => [
|
||||
'nullable',
|
||||
'email'
|
||||
]
|
||||
],
|
||||
'userpassword' => [
|
||||
'userpassword' => [
|
||||
'userpassword.*' => [
|
||||
'sometimes',
|
||||
'min:1'
|
||||
],
|
||||
'userpassword.*' => [
|
||||
'userpassword.*.*' => [
|
||||
'nullable',
|
||||
'min:8'
|
||||
]
|
||||
],
|
||||
'uidnumber' => [
|
||||
'uidnumber' => [
|
||||
'uidnumber.*' => [
|
||||
'sometimes',
|
||||
'max:1'
|
||||
],
|
||||
'uidnumber.*' => [
|
||||
'uidnumber.*.*' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
'max:65535'
|
||||
|
@ -54,6 +54,7 @@
|
||||
1.3.6.1.4.1.42.2.27.8.5.1:passwordPolicyRequest
|
||||
1.3.6.1.4.1.42.2.27.9.5.2:GetEffectiveRights control::May be used to determine what operations a given user may perform on a specified entry.
|
||||
1.3.6.1.4.1.1466.101.119.1:Dynamic Directory Services Refresh Request:RFC 2589
|
||||
1.3.6.1.4.1.1466.115.121.1.25:"guide" syntax-name:RFC 4517
|
||||
1.3.6.1.4.1.1466.20036:LDAP_NOTICE_OF_DISCONNECTION
|
||||
1.3.6.1.4.1.1466.20037:Transport Layer Security Extension:RFC 2830:This operation provides for TLS establishment in an LDAP association and is defined in terms of an LDAP extended request.
|
||||
1.3.6.1.4.1.1466.29539.1:LDAP_CONTROL_ATTR_SIZELIMIT
|
||||
|
254
package-lock.json
generated
254
package-lock.json
generated
@ -101,13 +101,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz",
|
||||
"integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
|
||||
"integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.26.10",
|
||||
"@babel/types": "^7.26.10",
|
||||
"@babel/parser": "^7.27.0",
|
||||
"@babel/types": "^7.27.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
"jsesc": "^3.0.2"
|
||||
@ -129,12 +129,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets": {
|
||||
"version": "7.26.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
|
||||
"integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz",
|
||||
"integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.26.5",
|
||||
"@babel/compat-data": "^7.26.8",
|
||||
"@babel/helper-validator-option": "^7.25.9",
|
||||
"browserslist": "^4.24.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
@ -154,9 +154,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.26.9.tgz",
|
||||
"integrity": "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz",
|
||||
"integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.25.9",
|
||||
@ -164,7 +164,7 @@
|
||||
"@babel/helper-optimise-call-expression": "^7.25.9",
|
||||
"@babel/helper-replace-supers": "^7.26.5",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
|
||||
"@babel/traverse": "^7.26.9",
|
||||
"@babel/traverse": "^7.27.0",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@ -184,9 +184,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-regexp-features-plugin": {
|
||||
"version": "7.26.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
|
||||
"integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz",
|
||||
"integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.25.9",
|
||||
@ -210,9 +210,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-define-polyfill-provider": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
|
||||
"integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz",
|
||||
"integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.22.6",
|
||||
@ -378,25 +378,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz",
|
||||
"integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
|
||||
"integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.26.9",
|
||||
"@babel/types": "^7.26.10"
|
||||
"@babel/template": "^7.27.0",
|
||||
"@babel/types": "^7.27.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
|
||||
"integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
|
||||
"integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.26.10"
|
||||
"@babel/types": "^7.27.0"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@ -651,12 +651,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
|
||||
"integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz",
|
||||
"integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
"@babel/helper-plugin-utils": "^7.26.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1188,12 +1188,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regenerator": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
|
||||
"integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz",
|
||||
"integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
"@babel/helper-plugin-utils": "^7.26.5",
|
||||
"regenerator-transform": "^0.15.2"
|
||||
},
|
||||
"engines": {
|
||||
@ -1325,9 +1325,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-typeof-symbol": {
|
||||
"version": "7.26.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz",
|
||||
"integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz",
|
||||
"integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.26.5"
|
||||
@ -1509,9 +1509,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
|
||||
"integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
@ -1521,30 +1521,30 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
|
||||
"integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
|
||||
"integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/parser": "^7.26.9",
|
||||
"@babel/types": "^7.26.9"
|
||||
"@babel/parser": "^7.27.0",
|
||||
"@babel/types": "^7.27.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz",
|
||||
"integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
|
||||
"integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/generator": "^7.26.10",
|
||||
"@babel/parser": "^7.26.10",
|
||||
"@babel/template": "^7.26.9",
|
||||
"@babel/types": "^7.26.10",
|
||||
"@babel/generator": "^7.27.0",
|
||||
"@babel/parser": "^7.27.0",
|
||||
"@babel/template": "^7.27.0",
|
||||
"@babel/types": "^7.27.0",
|
||||
"debug": "^4.3.1",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
@ -1553,9 +1553,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
|
||||
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
|
||||
"integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.25.9",
|
||||
@ -2021,9 +2021,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__generator": {
|
||||
"version": "7.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
|
||||
"integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
|
||||
"integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.0.0"
|
||||
@ -2040,9 +2040,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__traverse": {
|
||||
"version": "7.20.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
|
||||
"integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
|
||||
"integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.20.7"
|
||||
@ -2117,9 +2117,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
||||
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
@ -2248,12 +2248,12 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
|
||||
"integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
|
||||
"version": "22.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz",
|
||||
"integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node-forge": {
|
||||
@ -2335,9 +2335,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==",
|
||||
"version": "8.18.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
||||
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
@ -2804,9 +2804,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz",
|
||||
"integrity": "sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==",
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
|
||||
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@ -2834,13 +2834,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-polyfill-corejs2": {
|
||||
"version": "0.4.12",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
|
||||
"integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz",
|
||||
"integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.22.6",
|
||||
"@babel/helper-define-polyfill-provider": "^0.6.3",
|
||||
"@babel/helper-define-polyfill-provider": "^0.6.4",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@ -2870,12 +2870,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-polyfill-regenerator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
|
||||
"integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz",
|
||||
"integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-define-polyfill-provider": "^0.6.3"
|
||||
"@babel/helper-define-polyfill-provider": "^0.6.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||
@ -3023,9 +3023,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
|
||||
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
|
||||
"version": "5.3.5",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.5.tgz",
|
||||
"integrity": "sha512-ct1CHKtiobRimyGzmsSldEtM03E8fcEX4Tb3dGXz1V8faRwM50+vfHwTzOxB3IlKO7m+9vTH3s/3C6T2EAPeTA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -3315,9 +3315,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001703",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz",
|
||||
"integrity": "sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==",
|
||||
"version": "1.0.30001713",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001713.tgz",
|
||||
"integrity": "sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@ -4328,9 +4328,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.115",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.115.tgz",
|
||||
"integrity": "sha512-MN1nahVHAQMOz6dz6bNZ7apgqc9InZy7Ja4DBEVCTdeiUcegbyOYE9bi/f2Z/z6ZxLi0RxLpyJ3EGe+4h3w73A==",
|
||||
"version": "1.5.136",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.136.tgz",
|
||||
"integrity": "sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
@ -5292,9 +5292,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/html-entities": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
|
||||
"integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz",
|
||||
"integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -5447,9 +5447,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/http-parser-js": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz",
|
||||
"integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==",
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
|
||||
"integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/http-proxy": {
|
||||
@ -5467,9 +5467,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/http-proxy-middleware": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
|
||||
"integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz",
|
||||
"integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/http-proxy": "^1.17.8",
|
||||
@ -5634,9 +5634,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz",
|
||||
"integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.1.tgz",
|
||||
"integrity": "sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
@ -5923,9 +5923,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jquery.fancytree": {
|
||||
"version": "2.38.4",
|
||||
"resolved": "https://registry.npmjs.org/jquery.fancytree/-/jquery.fancytree-2.38.4.tgz",
|
||||
"integrity": "sha512-f4Fv5jZiZ6pBml/9txcJRAQDZpqQGGoJ8BUbicZKcO4CpgGbqBX9W7eQFwEaKQS0bxdVBLbqWQ9RoUK05ON2kQ==",
|
||||
"version": "2.38.5",
|
||||
"resolved": "https://registry.npmjs.org/jquery.fancytree/-/jquery.fancytree-2.38.5.tgz",
|
||||
"integrity": "sha512-6ntTplhfYKWz74GLpeeE9B62VqhsF+bd80gLZRDD1gl7Vv9WTqqQrCsrGMMu0PB6JLhNOXhf17xIcYpARG+N3g==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"jquery": ">=1.9"
|
||||
@ -6098,9 +6098,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/less": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/less/-/less-4.2.2.tgz",
|
||||
"integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/less/-/less-4.3.0.tgz",
|
||||
"integrity": "sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@ -6112,7 +6112,7 @@
|
||||
"lessc": "bin/lessc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=14"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"errno": "^0.1.1",
|
||||
@ -6549,9 +6549,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz",
|
||||
"integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==",
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -8240,9 +8240,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.85.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.85.1.tgz",
|
||||
"integrity": "sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag==",
|
||||
"version": "1.86.3",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.86.3.tgz",
|
||||
"integrity": "sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^4.0.0",
|
||||
@ -8832,9 +8832,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/std-env": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz",
|
||||
"integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==",
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
|
||||
"integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stream-browserify": {
|
||||
@ -9194,9 +9194,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unicode-canonical-property-names-ecmascript": {
|
||||
@ -9431,9 +9431,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.98.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
|
||||
"integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
|
||||
"version": "5.99.5",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.5.tgz",
|
||||
"integrity": "sha512-q+vHBa6H9qwBLUlHL4Y7L0L1/LlyBKZtS9FHNCQmtayxjI5RKC9yD8gpvLeqGv5lCQp1Re04yi0MF40pf30Pvg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.7",
|
||||
|
@ -1 +1 @@
|
||||
v2.0.3-rel
|
||||
v2.1.0-rel
|
||||
|
5
public/css/custom.css
vendored
5
public/css/custom.css
vendored
@ -2,7 +2,7 @@
|
||||
attribute#userPassword .select2-container--bootstrap-5 .select2-selection {
|
||||
font-size: inherit;
|
||||
width: 9em;
|
||||
border: #444054 1px solid;
|
||||
border: var(--bs-gray-500) 1px solid;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
@ -30,7 +30,10 @@ input.form-control.input-group-end {
|
||||
|
||||
.custom-tooltip-danger {
|
||||
--bs-tooltip-bg: var(--bs-danger);
|
||||
}
|
||||
|
||||
.custom-tooltip {
|
||||
--bs-tooltip-bg: var(--bs-gray-900);
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
|
2
public/js/custom.js
vendored
2
public/js/custom.js
vendored
@ -44,8 +44,10 @@ function getNode(item) {
|
||||
location.reload();
|
||||
break;
|
||||
case 500:
|
||||
case 555: // Missing Method
|
||||
$('.main-content').empty().append(e.responseText);
|
||||
break;
|
||||
|
||||
default:
|
||||
alert('Well that didnt work? Code ['+e.status+']');
|
||||
}
|
||||
|
4
resources/themes/architect/src/base.scss
vendored
4
resources/themes/architect/src/base.scss
vendored
@ -1,9 +1,9 @@
|
||||
/*!
|
||||
=========================================================
|
||||
* ArchitectUI HTML Theme Dashboard - v4.0.0
|
||||
* ArchitectUI HTML Theme Dashboard - v4.1.0
|
||||
=========================================================
|
||||
* Product Page: https://dashboardpack.com
|
||||
* Copyright 2023 DashboardPack (https://dashboardpack.com)
|
||||
* Copyright 2025 DashboardPack (https://dashboardpack.com)
|
||||
* Licensed under MIT (https://github.com/DashboardPack/architectui-html-theme-free/blob/master/LICENSE)
|
||||
=========================================================
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
22
resources/themes/architect/src/utils/_animate-override.scss
vendored
Normal file
22
resources/themes/architect/src/utils/_animate-override.scss
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
@use "sass:math";
|
||||
|
||||
@if $use-lightSpeedIn == true {
|
||||
@-webkit-keyframes lightSpeedIn {
|
||||
0% { -webkit-transform: translateX(100%) skewX(-$base-degrees); opacity: 0; }
|
||||
60% { -webkit-transform: translateX(-20%) skewX($base-degrees); opacity: 1; }
|
||||
80% { -webkit-transform: translateX(0%) skewX(calc(-1 * $base-degrees / 2)); opacity: 1; }
|
||||
100% { -webkit-transform: translateX(0%) skewX(0deg); opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes lightSpeedIn {
|
||||
0% { transform: translateX(100%) skewX(-$base-degrees); opacity: 0; }
|
||||
60% { transform: translateX(-20%) skewX($base-degrees); opacity: 1; }
|
||||
80% { transform: translateX(0%) skewX(calc(-1 * $base-degrees / 2)); opacity: 1; }
|
||||
100% { transform: translateX(0%) skewX(0deg); opacity: 1; }
|
||||
}
|
||||
|
||||
.lightSpeedIn {
|
||||
@include animate-prefixer(animation-name, lightSpeedIn);
|
||||
@include animate-prefixer(animation-timing-function, $base-timing-function-out);
|
||||
}
|
||||
}
|
@ -58,8 +58,7 @@ $use-all: true;
|
||||
"~animate-sass/animations/flippers/flipOutY";
|
||||
|
||||
// LIGHTSPEED
|
||||
@import "~animate-sass/animations/lightspeed/lightSpeedIn",
|
||||
"~animate-sass/animations/lightspeed/lightSpeedOut";
|
||||
@import "./_animate-override";
|
||||
|
||||
// ROTATE
|
||||
@import "~animate-sass/animations/rotate-enter/rotateIn",
|
||||
@ -98,4 +97,4 @@ $use-all: true;
|
||||
"~animate-sass/animations/zoom-exit/zoomOutDown",
|
||||
"~animate-sass/animations/zoom-exit/zoomOutLeft",
|
||||
"~animate-sass/animations/zoom-exit/zoomOutRight",
|
||||
"~animate-sass/animations/zoom-exit/zoomOutUp";
|
||||
"~animate-sass/animations/zoom-exit/zoomOutUp";
|
||||
|
@ -17,19 +17,4 @@
|
||||
@yield('page_actions')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('button[id=entry-edit]').on('click',function(item) {
|
||||
item.preventDefault();
|
||||
|
||||
if ($(this).hasClass('btn-dark'))
|
||||
return;
|
||||
|
||||
editmode();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
||||
</div>
|
@ -0,0 +1,9 @@
|
||||
<div class="alert alert-danger p-0" style="font-size: .80em;">
|
||||
<table class="table table-borderless table-danger p-0 m-0">
|
||||
<tr>
|
||||
<td class="align-top" style="width: 5%;"><i class="fas fa-fw fa-2x fa-exclamation-triangle"></i></td>
|
||||
<td>Unable to display this attribute as it has attribute tags [<strong>{!! $tags->join('</strong>, <strong>') !!}</strong>].<br>
|
||||
You can manage it with an LDIF import.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
@ -15,7 +15,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-attribute :o="$o" :edit="true" :new="$new ?? FALSE"/>
|
||||
<x-attribute :o="$o" :edit="$edit" :new="$new" :langtag="$langtag"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,19 +1,21 @@
|
||||
<!-- $o=Attribute::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
|
||||
@if (($edit ?? FALSE) && ! $o->is_rdn)
|
||||
<div class="input-group has-validation">
|
||||
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>($o->values->contains($value))]) name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! ($new ?? FALSE))>
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o">
|
||||
<div class="col-12">
|
||||
@foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value)
|
||||
@if($edit && (! $o->is_rdn))
|
||||
<div class="input-group has-validation">
|
||||
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! $new) @disabled($o->isDynamic())>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@else
|
||||
{{ $value }}
|
||||
@endif
|
||||
@endforeach
|
||||
@else
|
||||
<input type="text" class="form-control mb-1" value="{{ $value }}" disabled>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</x-attribute.layout>
|
@ -1,17 +1,17 @@
|
||||
<!-- @todo We are not handling redirect backs yet with updated photos -->
|
||||
<!-- $o=Binary\JpegPhoto::class -->
|
||||
<x-attribute.layout :edit="$edit" :new="false" :o="$o">
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" :langtag="$langtag">
|
||||
<table class="table table-borderless p-0 m-0">
|
||||
@foreach ($o->values_old as $value)
|
||||
@foreach($o->tagValuesOld() as $key => $value)
|
||||
<tr>
|
||||
@switch ($x=$f->buffer($value,FILEINFO_MIME_TYPE))
|
||||
@switch($x=$f->buffer($value,FILEINFO_MIME_TYPE))
|
||||
@case('image/jpeg')
|
||||
@default
|
||||
<td>
|
||||
<input type="hidden" name="{{ $o->name_lc }}[]" value="{{ md5($value) }}">
|
||||
<img @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
|
||||
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}">
|
||||
<img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
|
||||
|
||||
@if ($edit)
|
||||
@if($edit)
|
||||
<br>
|
||||
<!-- @todo TO IMPLEMENT -->
|
||||
<button class="btn btn-sm btn-danger deletable d-none mt-3" disabled><i class="fas fa-trash-alt"></i> @lang('Delete')</button>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- $o=Internal::class -->
|
||||
@foreach (old($o->name_lc,$o->values) as $value)
|
||||
@foreach(old($o->name_lc,$o->values) as $value)
|
||||
@if($loop->index)<br>@endif
|
||||
{{ $value }}
|
||||
@endforeach
|
@ -1,5 +1,5 @@
|
||||
<!-- $o=Internal\Timestamp::class -->
|
||||
@foreach (old($o->name_lc,$o->values) as $value)
|
||||
@foreach(old($o->name_lc,$o->values) as $value)
|
||||
@if($loop->index)<br>@endif
|
||||
{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}
|
||||
@endforeach
|
@ -1,8 +1,2 @@
|
||||
<!-- $o=Attribute::class -->
|
||||
<x-attribute.layout :edit="false" :new="false" :detail="true" :o="$o">
|
||||
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
|
||||
<div class="input-group">
|
||||
<input type="text" @class(['form-control','mb-1']) name="{{ $o->name_lc }}[]" value="{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}" @disabled(true)>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
||||
<!-- $o=NoAttrTags/Generic::class -->
|
||||
@include('components.form.disabled.datetime')
|
||||
|
@ -1 +1,2 @@
|
||||
@include('components.attribute.krblastfailedauth')
|
||||
<!-- $o=NoAttrTags/Generic::class -->
|
||||
@include('components.form.disabled.datetime')
|
@ -1 +1,2 @@
|
||||
@include('components.attribute.krblastfailedauth')
|
||||
<!-- $o=NoAttrTags/Generic::class -->
|
||||
@include('components.form.disabled.datetime')
|
@ -1,8 +1,2 @@
|
||||
<!-- $o=Attribute::class -->
|
||||
<x-attribute.layout :edit="false" :new="false" :detail="true" :o="$o">
|
||||
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
|
||||
<div class="input-group">
|
||||
<input type="text" @class(['form-control','mb-1']) name="{{ $o->name_lc }}[]" value="{{ $value }}" @disabled(true)>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
||||
<!-- $o=NoAttrTags/Generic::class -->
|
||||
@include('components.form.disabled.input')
|
@ -1 +1,2 @@
|
||||
@include('components.attribute.krblastfailedauth')
|
||||
<!-- $o=NoAttrTags/Generic::class -->
|
||||
@include('components.form.disabled.datetime')
|
@ -1,10 +1,10 @@
|
||||
<!-- @todo We are not handling redirect backs yet with updated passwords -->
|
||||
<!-- $o=Password::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||
@foreach($o->values_old as $value)
|
||||
<!-- $o=KrbPrincipleKey::class -->
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" :langtag="$langtag">
|
||||
@foreach($o->tagValuesOld($langtag) as $key => $value)
|
||||
@if($edit)
|
||||
<div class="input-group has-validation mb-3">
|
||||
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ md5($value) }}" @readonly(true)>
|
||||
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
@ -13,7 +13,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
{{ str_repeat('*',16) }}
|
||||
{{ $o->render_item_old($langtag.'.'.$key) }}
|
||||
@endif
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
@ -1,21 +1,21 @@
|
||||
<!-- $o=KrbTicketFlags::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||
@foreach(($o->values->count() ? $o->values : ($new ? [0] : NULL)) as $value)
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o">
|
||||
@foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $key => $value)
|
||||
@if($edit)
|
||||
<div id="32"></div>
|
||||
<div id="16"></div>
|
||||
|
||||
<div class="input-group has-validation mb-3">
|
||||
<input type="hidden" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ $value }}" @readonly(true)>
|
||||
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" @readonly(true)>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
{{ $value }}
|
||||
{{ $o->render_item_old($langtag.'.'.$key) }}
|
||||
@endif
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<!-- $o=Attribute::class -->
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o">
|
||||
@foreach(old($o->name_lc,$o->values) as $value)
|
||||
@if ($edit)
|
||||
<x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :loop="$loop" :value="$value"/>
|
||||
<!-- $o=Attribute/ObjectClass::class -->
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" :langtag="$langtag">
|
||||
@foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value)
|
||||
@if($edit)
|
||||
<x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :loop="$loop" :value="$value" :langtag="$langtag"/>
|
||||
@else
|
||||
{{ $value }}
|
||||
{{ $o->render_item_old($key) }}
|
||||
@if ($o->isStructural($value))
|
||||
<input type="hidden" name="{{ $o->name_lc }}[]" value="{{ $value }}">
|
||||
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}">
|
||||
<span class="float-end">@lang('structural')</span>
|
||||
@endif
|
||||
<br>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<!-- @todo We are not handling redirect backs yet with updated passwords -->
|
||||
<!-- $o=Password::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||
@foreach($o->values_old as $value)
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" :langtag="$langtag">
|
||||
@foreach($o->tagValuesOld($langtag) as $key => $value)
|
||||
@if($edit)
|
||||
<div class="input-group has-validation mb-3">
|
||||
<x-form.select id="userpassword_hash_{{$loop->index}}" name="userpassword_hash[]" :value="$o->hash($value)->id()" :options="$helpers" allowclear="false" :disabled="true"/>
|
||||
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ md5($value) }}" @readonly(true)>
|
||||
<x-form.select id="userpassword_hash_{{$loop->index}}" name="userpassword_hash[{{ $langtag }}][]" :value="$o->hash($value)->id()" :options="$helpers" allowclear="false" :disabled="true"/>
|
||||
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
{{ (($x=$o->hash($value)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '' }}{{ str_repeat('*',16) }}
|
||||
{{ $o->render_item_old($langtag.'.'.$key) }}
|
||||
@endif
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- $o=RDN::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o">
|
||||
@foreach(($o->values->count() ? $o->values : ['']) as $value)
|
||||
@if($edit)
|
||||
<div class="input-group has-validation mb-3">
|
||||
|
@ -0,0 +1 @@
|
||||
{!! $o->values->join('<br>') !!}
|
@ -1,9 +1,9 @@
|
||||
<span id="objectclass_{{$value}}">
|
||||
<div class="input-group has-validation">
|
||||
<!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way -->
|
||||
<input type="text" @class(['form-control','input-group-end','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)>
|
||||
<input type="text" @class(['form-control','input-group-end','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)>
|
||||
@if ($o->isStructural($value))
|
||||
<span class="input-group-end text-black-50">structural</span>
|
||||
<span class="input-group-end text-black-50">@lang('structural')</span>
|
||||
@else
|
||||
<span class="input-group-end"><i class="fas fa-fw fa-xmark"></i></span>
|
||||
@endif
|
||||
|
@ -1,15 +1,27 @@
|
||||
@use(App\Classes\LDAP\Attribute\Certificate)
|
||||
@use(App\Classes\LDAP\Attribute\CertificateList)
|
||||
@use(App\Classes\LDAP\Attribute\Binary\JpegPhoto)
|
||||
@use(App\Classes\LDAP\Attribute\ObjectClass)
|
||||
@php($clone=FALSE)
|
||||
<span class="p-0 m-0">
|
||||
@if($o->is_rdn)
|
||||
<br/>
|
||||
<span class="btn btn-sm btn-outline-focus mt-3" disabled><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</span>
|
||||
<button class="btn btn-sm btn-outline-focus mt-3" disabled><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</button>
|
||||
@elseif($edit && $o->can_addvalues)
|
||||
@switch(get_class($o))
|
||||
@case(JpegPhoto::class)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}" disabled><i class="fas fa-fw fa-plus"></i> @lang('Upload JpegPhoto')</span>
|
||||
|
||||
@case(Certificate::class)
|
||||
@case(CertificateList::class)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace')</span>
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#{{ $o->name }}-replace.addable').click(function(e) {
|
||||
alert('Sorry, not implemented yet');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
||||
@break
|
||||
|
||||
@case(ObjectClass::class)
|
||||
@ -51,6 +63,9 @@
|
||||
if (added_oc.indexOf(item) !== -1)
|
||||
return;
|
||||
|
||||
// Add our new OC to the list of OCs
|
||||
oc.push(item);
|
||||
|
||||
// Add attribute to the page
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
@ -151,7 +166,7 @@
|
||||
if (x.length) {
|
||||
x.remove();
|
||||
|
||||
// Add this to the must attrs list, because its been rendered
|
||||
// Add this to the must attrs list, because its been rendered
|
||||
} else {
|
||||
attrs.push(mayitem);
|
||||
}
|
||||
@ -217,8 +232,24 @@
|
||||
@append
|
||||
@break
|
||||
|
||||
@case(JpegPhoto::class)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-upload" disabled><i class="fas fa-fw fa-file-arrow-up"></i> @lang('Upload JpegPhoto')</span>
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#{{ $o->name }}-upload.addable').click(function(e) {
|
||||
alert('Sorry, not implemented yet');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
||||
@break
|
||||
|
||||
<!-- All other attributes -->
|
||||
@default
|
||||
@if($o->isDynamic()) @break @endif
|
||||
@php($clone=TRUE)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-addnew"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span>
|
||||
|
||||
@ -229,8 +260,11 @@
|
||||
// Create a new entry when Add Value clicked
|
||||
$('#{{ $o->name }}-addnew.addable').click(function (item) {
|
||||
var cln = $(this).parent().parent().find('input:last').parent().clone();
|
||||
cln.find('input:last').attr('value','').attr('placeholder', '[@lang('NEW')]');
|
||||
cln.appendTo('#'+item.currentTarget.id.replace('-addnew',''));
|
||||
cln.find('input:last')
|
||||
.attr('value','')
|
||||
.attr('placeholder', '[@lang('NEW')]')
|
||||
.addClass('border-focus')
|
||||
.appendTo('#'+item.currentTarget.id.replace('-addnew',''));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -0,0 +1,8 @@
|
||||
<!-- $o=Attribute::class -->
|
||||
<x-attribute.layout :edit="false" :new="false" :o="$o" :detail="true">
|
||||
@foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $value)
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control mb-1" value="{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}" disabled>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
8
resources/views/components/form/disabled/input.blade.php
Normal file
8
resources/views/components/form/disabled/input.blade.php
Normal file
@ -0,0 +1,8 @@
|
||||
<!-- $o=Attribute::class -->
|
||||
<x-attribute.layout :edit="false" :new="false" :o="$o" :detail="true">
|
||||
@foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $value)
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control mb-1" value="{{ $value }}" disabled>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
@ -66,7 +66,7 @@
|
||||
@endif
|
||||
|
||||
@isset($options)
|
||||
@if($options->count() === 1)
|
||||
@if(($autoselect ?? FALSE) && $options->count() === 1)
|
||||
$('#{{ $id ?? $name }}')
|
||||
.val('{{ $options->first()['id'] }}')
|
||||
.trigger("change")
|
||||
|
28
resources/views/components/syntax/certificate.blade.php
Normal file
28
resources/views/components/syntax/certificate.blade.php
Normal file
@ -0,0 +1,28 @@
|
||||
@use(App\Classes\LDAP\Attribute\Certificate)
|
||||
|
||||
<!-- $o=Certificate::class -->
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" langtag="binary">
|
||||
@foreach($o->tagValuesOld('binary') as $key => $value)
|
||||
<!-- If this attribute is not handle, it'll be an Attribute::class, we'll just render it normally -->
|
||||
@if(($o instanceof Certificate) && $edit)
|
||||
<input type="hidden" name="name={{ $o->name_lc }}[binary][]" value="{{ md5($value) }}">
|
||||
|
||||
<div class="input-group has-validation mb-3">
|
||||
<textarea class="form-control mb-1 font-monospace" rows="{{ count(explode("\n",$x=$o->certificate())) }}" style="overflow: hidden; font-size: 90%;" disabled>{{ $x }}</textarea>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-helper">
|
||||
@lang('Certificate Subject'): <strong>{{ $o->subject($loop->index) }}</strong><br/>
|
||||
{{ ($expire=$o->expires($loop->index))->isPast() ? __('Expired') : __('Expires') }}: <strong>{{ $expire->format(config('pla.datetime_format','Y-m-d H:i:s')) }}</strong>
|
||||
</div>
|
||||
|
||||
@else
|
||||
<span class="form-control mb-1"><pre class="m-0">{{ $o->render_item_old('binary.'.$key) }}</pre></span>
|
||||
@endif
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
@ -0,0 +1,7 @@
|
||||
<!-- $o=CertificateList::class -->
|
||||
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" langtag="binary">
|
||||
@foreach($o->tagValuesOld('binary') as $key => $value)
|
||||
<!-- If this attribute is not handle, it'll be an Attribute::class, we'll just render it normally -->
|
||||
<span class="form-control mb-1"><pre class="m-0">{{ $o->render_item_old('binary.'.$key) }}</pre></span>
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
@ -5,7 +5,7 @@
|
||||
<p>{{ __('Entry updated') }}</p>
|
||||
<ul style="list-style-type: square;">
|
||||
@foreach (session()->pull('updated') as $key => $o)
|
||||
<li><abbr title="{{ $o->description }}">{{ $o->name }}</abbr>: {{ $o->values->map(fn($item,$key)=>$o->render_item_new($key))->join(',') }}</li>
|
||||
<li><abbr title="{{ $o->description }}">{{ $o->name }}</abbr>: {{ $o->values->dot()->filter()->join(',') }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -26,6 +26,12 @@
|
||||
<x-attribute :o="$o->getObject('entryuuid')" :na="__('Unknown')"/>
|
||||
</th>
|
||||
</tr>
|
||||
@if($langtags->count())
|
||||
<tr class="mt-1">
|
||||
<td class="p-0 pe-2">Tags</td>
|
||||
<th class="p-0">{{ $langtags->join(', ') }}</th>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<div class="row">
|
||||
|
||||
<div class="col-12 col-xl-3">
|
||||
<select id="attributetype" class="form-control">
|
||||
<option value="-all-">-all-</option>
|
||||
|
@ -2,14 +2,17 @@
|
||||
<div class="col-12 col-xl-3">
|
||||
<select id="objectclass" class="form-control">
|
||||
<option value="-all-">-all-</option>
|
||||
@foreach ($objectclasses as $o)
|
||||
<option value="{{ $o->name_lc }}">{{ $o->name }}</option>
|
||||
@foreach($objectclasses->groupBy(fn($item)=>$item->isStructural()) as $oo)
|
||||
<optgroup label="{{ __($oo->first()->isStructural() ? 'Structural' : 'Auxillary') }} Object Class"></optgroup>
|
||||
@foreach($oo as $o)
|
||||
<option value="{{ $o->name_lc }}">{{ $o->name }}</option>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-xl-9">
|
||||
@foreach ($objectclasses as $o)
|
||||
@foreach($objectclasses as $o)
|
||||
<span id="oc-{{ $o->name_lc }}">
|
||||
<table class="schema table table-sm table-bordered table-striped">
|
||||
<thead>
|
||||
@ -32,10 +35,10 @@
|
||||
<td>@lang('Inherits from')</td>
|
||||
<td colspan="3">
|
||||
<strong>
|
||||
@if ($o->sup->count() === 0)
|
||||
@if($o->sup->count() === 0)
|
||||
@lang('(none)')
|
||||
@else
|
||||
@foreach ($o->sup as $sup)
|
||||
@foreach($o->sup as $sup)
|
||||
@if($loop->index)</strong> <strong>@endif
|
||||
<a class="objectclass" id="{{ strtolower($sup) }}" href="#{{ strtolower($sup) }}">{{ $sup }}</a>
|
||||
@endforeach
|
||||
@ -48,12 +51,12 @@
|
||||
<td>@lang('Parent to')</td>
|
||||
<td colspan="3">
|
||||
<strong>
|
||||
@if (strtolower($o->name) === 'top')
|
||||
@if(strtolower($o->name) === 'top')
|
||||
<a class="objectclass" id="-all-">(all)</a>
|
||||
@elseif (! $o->getChildObjectClasses()->count())
|
||||
@elseif(! $o->getChildObjectClasses()->count())
|
||||
@lang('(none)')
|
||||
@else
|
||||
@foreach ($o->getChildObjectClasses() as $childoc)
|
||||
@foreach($o->getChildObjectClasses() as $childoc)
|
||||
@if($loop->index)</strong> <strong>@endif
|
||||
<a class="objectclass" id="{{ strtolower($childoc) }}" href="#{{ strtolower($childoc) }}">{{ $childoc }}</a>
|
||||
@endforeach
|
||||
@ -75,7 +78,7 @@
|
||||
<tr>
|
||||
<td>
|
||||
<ul class="ps-3" style="list-style-type: square;">
|
||||
@foreach ($o->getMustAttrs(TRUE) as $oo)
|
||||
@foreach($o->getMustAttrs(TRUE) as $oo)
|
||||
<li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@ -97,7 +100,7 @@
|
||||
<tr>
|
||||
<td>
|
||||
<ul class="ps-3" style="list-style-type: square;">
|
||||
@foreach ($o->getMayAttrs(TRUE) as $oo)
|
||||
@foreach($o->getMayAttrs(TRUE) as $oo)
|
||||
<li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
@ -1,12 +1,15 @@
|
||||
@use(App\Ldap\Entry)
|
||||
|
||||
@extends('layouts.dn')
|
||||
|
||||
@section('page_title')
|
||||
@include('fragment.dn.header',['o'=>($oo=$server->fetch(old('container',$container)))])
|
||||
@include('fragment.dn.header',[
|
||||
'o'=>($oo=$server->fetch(old('container',$container))),
|
||||
'langtags'=>collect(),
|
||||
])
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
<x-error/>
|
||||
|
||||
<div class="row">
|
||||
<div class="offset-1 col-10">
|
||||
<div class="main-card mb-3 card">
|
||||
@ -28,7 +31,8 @@
|
||||
<div class="col-12 col-md-6">
|
||||
<x-form.select
|
||||
id="objectclass"
|
||||
name="objectclass[]"
|
||||
name="objectclass[{{ Entry::TAG_NOTAG }}][]"
|
||||
old="objectclass.{{ Entry::TAG_NOTAG }}"
|
||||
:label="__('Select a Structural ObjectClass...')"
|
||||
:options="($oc=$server->schema('objectclasses'))
|
||||
->filter(fn($item)=>$item->isStructural())
|
||||
@ -66,8 +70,8 @@
|
||||
@endsection
|
||||
|
||||
@section('page-scripts')
|
||||
|
||||
<script type="text/javascript">
|
||||
var oc = {!! $oo->getObject('objectclass')->values !!};
|
||||
var rdn_attr;
|
||||
|
||||
function editmode() {
|
||||
@ -96,31 +100,35 @@
|
||||
}
|
||||
|
||||
$(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
|
||||
@if($step === 2)
|
||||
var oc = {!! $o->getObject('objectclass')->values !!};
|
||||
|
||||
$('#newattr').on('change',function(item) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '{{ url('entry/attr/add') }}/'+item.target.value,
|
||||
data: {
|
||||
objectclasses: oc,
|
||||
},
|
||||
cache: false,
|
||||
beforeSend: function() {},
|
||||
success: function(data) {
|
||||
$('#newattrs').append(data);
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status != 412)
|
||||
alert('That didnt work? Please try again....');
|
||||
},
|
||||
});
|
||||
|
||||
// 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();
|
||||
});
|
||||
|
||||
// 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();
|
||||
});
|
||||
@endif
|
||||
|
||||
editmode();
|
||||
});
|
||||
|
@ -1,7 +1,15 @@
|
||||
@use(App\Ldap\Entry)
|
||||
|
||||
@extends('layouts.dn')
|
||||
|
||||
@section('page_title')
|
||||
@include('fragment.dn.header',['o'=>($o ?? $o=$server->fetch($dn))])
|
||||
@include('fragment.dn.header',[
|
||||
'o'=>($o ?? $o=$server->fetch($dn)),
|
||||
'langtags'=>($langtags=$o->getLangTags()
|
||||
->flatMap(fn($item)=>$item->values())
|
||||
->unique()
|
||||
->sort())
|
||||
])
|
||||
@endsection
|
||||
|
||||
@section('page_actions')
|
||||
@ -9,25 +17,30 @@
|
||||
<div class="col">
|
||||
<div class="action-buttons float-end">
|
||||
<ul class="nav">
|
||||
@if(isset($page_actions) && $page_actions->contains('export'))
|
||||
@if(isset($page_actions) && $page_actions->get('create'))
|
||||
<li>
|
||||
<button class="btn btn-outline-dark p-1 m-1" id="entry-copy-move" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('New Child')" disabled><i class="fas fa-fw fa-diagram-project fs-5"></i></button>
|
||||
</li>
|
||||
@endif
|
||||
@if(isset($page_actions) && $page_actions->get('export'))
|
||||
<li>
|
||||
<span id="entry-export" data-bs-toggle="modal" data-bs-target="#page-modal">
|
||||
<button class="btn btn-outline-dark p-1 m-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Export')"><i class="fas fa-fw fa-download fs-5"></i></button>
|
||||
</span>
|
||||
</li>
|
||||
@endif
|
||||
@if(isset($page_actions) && $page_actions->contains('copy'))
|
||||
@if(isset($page_actions) && $page_actions->get('copy'))
|
||||
<li>
|
||||
<button class="btn btn-outline-dark p-1 m-1" id="entry-copy-move" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Copy/Move')" disabled><i class="fas fa-fw fa-copy fs-5"></i></button>
|
||||
</li>
|
||||
@endif
|
||||
@if((isset($page_actions) && $page_actions->contains('edit')) || old())
|
||||
@if(isset($page_actions) && $page_actions->get('edit'))
|
||||
<li>
|
||||
<button class="btn btn-outline-dark p-1 m-1" id="entry-edit" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Edit Entry')"><i class="fas fa-fw fa-edit fs-5"></i></button>
|
||||
</li>
|
||||
@endif
|
||||
<!-- @todo Dont offer the delete button for an entry with children -->
|
||||
@if(isset($page_actions) && $page_actions->contains('delete'))
|
||||
@if(isset($page_actions) && $page_actions->get('delete'))
|
||||
<li>
|
||||
<span id="entry-delete" data-bs-toggle="modal" data-bs-target="#page-modal">
|
||||
<button class="btn btn-outline-danger p-1 m-1" data-bs-custom-class="custom-tooltip-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Delete Entry')"><i class="fas fa-fw fa-trash-can fs-5"></i></button>
|
||||
@ -38,6 +51,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@if(($x=$o->getOtherTags()->filter(fn($item)=>$item->diff(['binary'])->count()))->count())
|
||||
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
|
||||
This entry has [<strong>{!! $x->flatten()->join('</strong>, <strong>') !!}</strong>] tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those tags with an LDIF import.
|
||||
</div>
|
||||
@elseif(($x=$o->getLangMultiTags())->count())
|
||||
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
|
||||
This entry has multi-language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
@ -48,12 +75,9 @@
|
||||
<div class="main-card mb-3 card">
|
||||
<div class="card-body">
|
||||
<div class="card-header-tabs">
|
||||
<ul class="nav nav-tabs">
|
||||
<ul class="nav nav-tabs mb-0">
|
||||
<li class="nav-item"><a data-bs-toggle="tab" href="#attributes" class="nav-link active">@lang('Attributes')</a></li>
|
||||
<li class="nav-item"><a data-bs-toggle="tab" href="#internal" class="nav-link">@lang('Internal')</a></li>
|
||||
@env(['local'])
|
||||
<li class="nav-item"><a data-bs-toggle="tab" href="#debug" class="nav-link">@lang('Debug')</a></li>
|
||||
@endenv
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
@ -63,10 +87,57 @@
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="dn" value="">
|
||||
<div class="card-header border-bottom-0">
|
||||
<div class="btn-actions-pane-right">
|
||||
<div role="group" class="btn-group-sm nav btn-group">
|
||||
@foreach($langtags->prepend(Entry::TAG_NOTAG)->push('+') as $tag)
|
||||
<a data-bs-toggle="tab" href="#tab-lang-{{ $tag ?: '_default' }}" class="btn btn-outline-light border-dark-subtle @if(! $loop->index) active @endif @if($loop->last)ndisabled @endif">
|
||||
@switch($tag)
|
||||
@case(Entry::TAG_NOTAG)
|
||||
<i class="fas fa-fw fa-border-none" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" title="@lang('No Lang Tag')"></i>
|
||||
@break
|
||||
|
||||
@foreach ($o->getVisibleAttributes() as $ao)
|
||||
<x-attribute-type :edit="true" :o="$ao"/>
|
||||
@endforeach
|
||||
@case('+')
|
||||
<!-- @todo To implement -->
|
||||
<i class="fas fa-fw fa-plus text-dark" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" title="@lang('Add Lang Tag')"></i>
|
||||
@break
|
||||
|
||||
@default
|
||||
<span class="f16" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" title="{{ strtoupper($tag) }}"><i class="flag {{ $tag }}"></i></span>
|
||||
@endswitch
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
@foreach($langtags as $tag)
|
||||
<div class="tab-pane @if(! $loop->index) active @endif" id="tab-lang-{{ $tag ?: '_default' }}" role="tabpanel">
|
||||
@switch($tag)
|
||||
@case(Entry::TAG_NOTAG)
|
||||
@foreach ($o->getVisibleAttributes($tag) as $ao)
|
||||
<x-attribute-type :edit="true" :o="$ao" :langtag="$tag"/>
|
||||
@endforeach
|
||||
@break
|
||||
|
||||
@case('+')
|
||||
<div class="ms-auto mt-4 alert alert-warning p-2" style="max-width: 30em; font-size: 0.80em;">
|
||||
It is not possible to create new language tags at the moment. This functionality should come soon.<br>
|
||||
You can create them with an LDIF import though.
|
||||
</div>
|
||||
@break
|
||||
|
||||
@default
|
||||
@foreach ($o->getVisibleAttributes($langtag=sprintf('lang-%s',$tag)) as $ao)
|
||||
<x-attribute-type :edit="true" :o="$ao" :langtag="$langtag"/>
|
||||
@endforeach
|
||||
@endswitch
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('fragment.dn.add_attr')
|
||||
</form>
|
||||
@ -80,26 +151,11 @@
|
||||
</div>
|
||||
|
||||
<!-- Internal Attributes -->
|
||||
<div class="tab-pane" id="internal" role="tabpanel">
|
||||
<div class="tab-pane mt-3" id="internal" role="tabpanel">
|
||||
@foreach ($o->getInternalAttributes() as $ao)
|
||||
<x-attribute-type :o="$ao"/>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<!-- Debug -->
|
||||
<div class="tab-pane" id="debug" role="tabpanel">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
@dump($o)
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@dump($o->getAttributes())
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@dump(['available'=>$o->getAvailableAttributes()->pluck('name'),'missing'=>$o->getMissingAttributes()->pluck('name')])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -154,6 +210,15 @@
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('button[id=entry-edit]').on('click',function(item) {
|
||||
item.preventDefault();
|
||||
|
||||
if ($(this).hasClass('btn-dark'))
|
||||
return;
|
||||
|
||||
editmode();
|
||||
});
|
||||
|
||||
$('#newattr').on('change',function(item) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
|
@ -7,12 +7,12 @@
|
||||
|
||||
<div class="modal-body">
|
||||
<table class="table table-bordered p-1">
|
||||
@foreach(($up=$o->getObject('userpassword'))->values as $key => $value)
|
||||
@foreach(($up=$o->getObject('userpassword'))->values->dot() as $dotkey => $value)
|
||||
<tr>
|
||||
<th>Check</th>
|
||||
<td>{{ $up->render_item_old($key) }}</td>
|
||||
<td>{{ $up->render_item_old($dotkey) }}</td>
|
||||
<td>
|
||||
<input type="password" style="width: 90%" name="password[{{$key}}]"> <i class="fas fa-fw fa-lock"></i>
|
||||
<input type="password" style="width: 90%" name="password[{{ $dotkey }}]"> <i class="fas fa-fw fa-lock"></i>
|
||||
<div class="invalid-feedback pb-2">
|
||||
@lang('Invalid Password')
|
||||
</div>
|
||||
|
@ -1,7 +1,12 @@
|
||||
@extends('home')
|
||||
|
||||
@section('page_title')
|
||||
@include('fragment.dn.header')
|
||||
@include('fragment.dn.header',[
|
||||
'langtags'=>($langtags=$o->getLangTags()
|
||||
->flatMap(fn($item)=>$item->values())
|
||||
->unique()
|
||||
->sort())
|
||||
])
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
@ -23,6 +28,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute</th>
|
||||
<th>Tag</th>
|
||||
<th>OLD</th>
|
||||
<th>NEW</th>
|
||||
</tr>
|
||||
@ -31,17 +37,26 @@
|
||||
<tbody>
|
||||
@foreach ($o->getObjects()->filter(fn($item)=>$item->isDirty()) as $key => $oo)
|
||||
<tr>
|
||||
<th rowspan="{{ $x=max($oo->values->keys()->max(),$oo->values_old->keys()->max())+1}}">
|
||||
<th rowspan="{{ $x=max($oo->values->dot()->keys()->count(),$oo->values_old->dot()->keys()->count())+1}}">
|
||||
<abbr title="{{ $oo->description }}">{{ $oo->name }}</abbr>
|
||||
</th>
|
||||
@for($xx=0;$xx<$x;$xx++)
|
||||
@if($xx)
|
||||
|
||||
@foreach($oo->values->dot()->keys()->merge($oo->values_old->dot()->keys())->unique() as $dotkey)
|
||||
@if($loop->index)
|
||||
</tr><tr>
|
||||
@endif
|
||||
|
||||
<td>{{ (($r=$oo->render_item_old($xx)) !== NULL) ? $r : '['.strtoupper(__('New Value')).']' }}</td>
|
||||
<td>{{ (($r=$oo->render_item_new($xx)) !== NULL) ? $r : '['.strtoupper(__('Deleted')).']' }}<input type="hidden" name="{{ $key }}[]" value="{{ Arr::get($oo->values,$xx) }}"></td>
|
||||
@endfor
|
||||
<th>
|
||||
{{ $dotkey }}
|
||||
</th>
|
||||
|
||||
@if((! Arr::get($oo->values_old->dot(),$dotkey)) && (! Arr::get($oo->values->dot(),$dotkey)))
|
||||
<td colspan="2" class="text-center">@lang('Ignoring blank value')</td>
|
||||
@else
|
||||
<td>{{ (($r=$oo->render_item_old($dotkey)) !== NULL) ? $r : '['.strtoupper(__('New Value')).']' }}</td>
|
||||
<td>{{ (($r=$oo->render_item_new($dotkey)) !== NULL) ? $r : '['.strtoupper(__('Deleted')).']' }}<input type="hidden" name="{{ $key }}[{{ collect(explode('.',$dotkey))->first() }}][]" value="{{ Arr::get($oo,$dotkey) }}"></td>
|
||||
@endif
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
dn: cn=tech_staff,dc=example.com
|
||||
cn: tech_staff
|
||||
labeleduri: ldap:///ou=People,o=Simpsons?uid?one?(&(sn=Simpson)(|(uidNumber
|
||||
=1000)(uidNumber=1001)))
|
||||
labeleduri: ldap:///dc=example.com?uid?one?(|(cn=kerberos)(uidNumber=*))
|
||||
objectclass: nisMailAlias
|
||||
objectclass: labeledURIObject
|
||||
|
7
tests/server/openldap/schema/modify/00-config.ldif
Normal file
7
tests/server/openldap/schema/modify/00-config.ldif
Normal file
@ -0,0 +1,7 @@
|
||||
dn: olcDatabase={0}config,cn=config
|
||||
changetype: modify
|
||||
add: olcRootPW
|
||||
olcRootPW:: c2VjcmV0
|
||||
|
||||
add: olcRootDN
|
||||
olcRootDN: cn=config
|
25
tests/server/openldap/schema/modify/00-mapsize.ldif
Normal file
25
tests/server/openldap/schema/modify/00-mapsize.ldif
Normal file
@ -0,0 +1,25 @@
|
||||
dn: olcDatabase={3}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={4}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={5}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={6}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={7}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
4
tests/server/openldap/schema/modify/00-sizelimit.ldif
Normal file
4
tests/server/openldap/schema/modify/00-sizelimit.ldif
Normal file
@ -0,0 +1,4 @@
|
||||
dn: olcDatabase={4}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcSizeLimit
|
||||
olcSizeLimit: 2000
|
11
tests/server/openldap/schema/modify/40-dynlist-options.ldif
Normal file
11
tests/server/openldap/schema/modify/40-dynlist-options.ldif
Normal file
@ -0,0 +1,11 @@
|
||||
dn: olcOverlay=dynlist,olcDatabase={4}mdb,cn=config
|
||||
changetype: add
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcDynListConfig
|
||||
olcOverlay: dynlist
|
||||
olcDynListAttrSet: nisMailAlias labeledURI
|
||||
#olcDynListAttrSet: groupOfURLs memberURL memberOf
|
||||
#olcDynListAttrSet: groupOfURLs memberURL member+dgMemberOf
|
||||
#olcDynListAttrSet: groupOfURLs memberURL member
|
||||
#olcDynListAttrSet: groupOfURLs memberURL member
|
||||
#olcDynListAttrSet: groupOfURLs labeledURI member
|
Loading…
x
Reference in New Issue
Block a user