Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F120822988
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/composer.json b/src/composer.json
index 82d6274e..65aa1369 100644
--- a/src/composer.json
+++ b/src/composer.json
@@ -1,90 +1,90 @@
{
"name": "kolab/kolab4",
"type": "project",
"description": "Kolab 4",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"repositories": [
{
"type": "vcs",
"url": "https://git.kolab.org/diffusion/PNL/php-net_ldap3.git"
}
],
"require": {
"php": "^8.2",
"bacon/bacon-qr-code": "^2.0",
"barryvdh/laravel-dompdf": "^2.0.1",
"doctrine/dbal": "^3.6",
"dyrynda/laravel-nullable-fields": "^4.3.0",
"garethp/php-ews": "~0.10.3",
"guzzlehttp/guzzle": "^7.8.0",
"jeremy379/laravel-openid-connect": "~2.4.0",
"kolab/net_ldap3": "dev-master",
"laravel/framework": "^11.0",
"laravel/horizon": "^5.9",
"laravel/octane": "^2.3",
"laravel/passport": "^12.0",
"laravel/tinker": "^2.8",
"league/flysystem-aws-s3-v3": "^3.0",
"mlocati/spf-lib": "^3.1",
"mollie/laravel-mollie": "^3.0",
"pear/crypt_gpg": "^1.6.6",
"pear/mail_mime": "~1.10.11",
"predis/predis": "^2.0",
"sabre/vobject": "^4.5",
"spatie/laravel-translatable": "^6.5",
"spomky-labs/otphp": "~10.0.0",
"stripe/stripe-php": "^10.7"
},
"require-dev": {
"code-lts/doctum": "dev-main",
"diablomedia/arcanist-extensions": "^1.1",
"friendsofphp/php-cs-fixer": "^3.0",
"larastan/larastan": "^3.4",
- "laravel/dusk": "~8.2.2",
+ "laravel/dusk": "~8.3.0",
"mockery/mockery": "^1.5",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^10.5.32"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"include"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "stable",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
}
diff --git a/src/resources/themes/forms.scss b/src/resources/themes/forms.scss
index ebfcc249..f56b7441 100644
--- a/src/resources/themes/forms.scss
+++ b/src/resources/themes/forms.scss
@@ -1,263 +1,263 @@
.list-input {
& > div {
&:not(:last-child) {
margin-bottom: -1px;
input,
a.btn {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
}
&:not(:first-child) {
input,
a.btn {
border-top-right-radius: 0;
border-top-left-radius: 0;
}
}
}
input.is-invalid {
z-index: 2;
}
.btn svg {
vertical-align: middle;
}
}
.acl-input {
select.acl,
select.mod-user {
max-width: fit-content;
}
}
.password-input {
ul {
svg {
width: 0.75em !important;
}
span {
padding: 0 0.05em;
}
}
}
.range-input {
display: flex;
label {
margin-right: 0.5em;
min-width: 4em;
text-align: right;
line-height: 1.7;
}
}
.input-group-activable {
&.active {
:not(.activable) {
display: none;
}
}
&:not(.active) {
.activable {
display: none;
}
}
// Label is always visible
.label {
color: $body-color;
display: initial !important;
}
.input-group-text {
border-color: transparent;
background: transparent;
padding-left: 0;
&:not(.label) {
flex: 1;
}
}
}
// An input group with a select and input, where input is displayed
// only for some select values
.input-group-select {
&:not(.selected) {
input {
display: none;
}
select {
border-bottom-right-radius: .25rem !important;
border-top-right-radius: .25rem !important;
}
}
input {
border-bottom-right-radius: .25rem !important;
border-top-right-radius: .25rem !important;
}
}
.form-control-plaintext .btn-sm {
margin-top: -0.25rem;
}
.buttons {
& > button + button {
margin-left: .5em;
}
.accordion-header > & {
position: absolute;
display: flex;
align-items: center;
top: 0;
right: 3.25rem;
height: 2.5rem;
z-index: 3;
}
}
// Various improvements for mobile
@include media-breakpoint-down(sm) {
.row.mb-3 {
margin-bottom: 0.5rem !important;
}
.nav-tabs {
.nav-link {
white-space: nowrap;
padding: 0.5rem 0.75rem;
}
}
.tab-content {
margin-top: 0.5rem;
}
.col-form-label {
color: #666;
font-size: 95%;
}
.row.plaintext .col-form-label {
padding-bottom: 0;
}
form.read-only.short label {
width: 35%;
& + * {
width: 65%;
}
}
.row.checkbox {
position: relative;
& > div {
padding-top: 0 !important;
- input[type=checkbox] {
+ input[type="checkbox"] {
position: absolute;
top: 0.5rem;
right: 1rem;
}
}
label {
padding-right: 2.5rem;
}
}
}
.file-drop-area {
color: grey;
font-size: 0.9rem;
font-weight: normal;
line-height: 2;
border: 1px dashed #bbb;
border-radius: 0.5em;
padding: 0.5em;
cursor: pointer;
position: relative;
margin-top: -0.5rem;
input {
position: absolute;
height: 10px;
}
&.dragactive {
border: 1px dashed #aaa;
}
&.dragover {
background-color: rgba($main-color, 0.25);
border: 1px dashed $main-color;
color: $main-color;
}
}
.world-map {
height: 100%;
width: 100%;
text-align: center;
overflow: auto;
svg {
height: 100%;
.bg {
fill: $gray-600;
}
[cc] {
fill: white;
stroke: $gray-600;
stroke-width: 0.25px;
cursor: pointer;
}
[cc][aria-selected="true"] {
fill: $main-color;
stroke: #fff;
}
[cc][data-location] {
fill: $success;
stroke: #fff;
}
[cc]:focus, [cc]:hover {
fill: lighten($main-color, 20%) !important;
stroke: $main-color !important;
}
}
& + .tools {
position: absolute;
right: 0;
bottom: 0;
background-color: rgba(211, 211, 211, 90%);
}
& + .tools + .location {
position: absolute;
top: 0;
background-color: rgba(211, 211, 211, 90%);
max-width: calc(100% - 1em);
overflow: hidden;
text-overflow: ellipsis;
}
}
diff --git a/src/resources/vue/Widgets/PasswordInput.vue b/src/resources/vue/Widgets/PasswordInput.vue
index 3c8dbe0c..2fbedb18 100644
--- a/src/resources/vue/Widgets/PasswordInput.vue
+++ b/src/resources/vue/Widgets/PasswordInput.vue
@@ -1,98 +1,99 @@
<template>
<div class="password-input">
- <div :id="prefix + 'password_input'">
+ <div :id="prefixed('password_input')">
<input type="password"
class="form-control"
autocomplete="new-password"
- :id="prefix + 'password'"
+ :id="prefixed('password')"
:placeholder="$t(placeholder ? placeholder : 'form.password')"
v-model="password"
@input="onInput"
>
<input type="password"
class="form-control mt-2"
autocomplete="new-password"
- :id="prefix + 'password_confirmation'"
+ :id="prefixed('password_confirmation')"
:placeholder="$t('form.password-confirm')"
v-model="password_confirmation"
@input="onInputConfirm"
>
</div>
- <ul v-if="policy.length" :id="prefix + 'password_policy'" class="list-group pt-2">
+ <ul v-if="policy.length" :id="prefixed('password_policy')" class="list-group pt-2">
<li v-for="rule in policy" :key="rule.label" class="list-group-item border-0 p-0">
<svg-icon v-if="rule.status" icon="check" class="text-success"></svg-icon>
<span v-else class="text-secondary">•</span>
<small class="ps-1 form-text">{{ rule.name }}</small>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
focus: { type: Boolean, default: false },
value: { type: Object, default: () => {} },
placeholder: { type: String, default: '' },
prefix: { type: String, default: '' },
user: { type: [String, Number], default: '' }
},
data() {
return {
password: '',
password_confirmation: '',
policy: [],
}
},
mounted() {
this.checkPolicy('')
const input = $('#password')[0]
- if (this.prefix == '') {
- this.prefix = $(input.form).data('validation-prefix') || ''
- }
+ this.formPrefix = $(input.form).data('validation-prefix')
$(input.form).on('reset', () => { this.checkPolicy('') })
if (this.focus) {
input.focus()
}
},
methods: {
checkPolicy(password) {
if (this.cancelToken) {
this.cancelToken.cancel()
}
const post = { password, user: this.user }
if (!post.user && this.$root.authInfo) {
post.user = this.$root.authInfo.id
}
const cancelToken = axios.CancelToken;
this.cancelToken = cancelToken.source();
axios.post('/api/auth/password-policy-check', post, { cancelToken: this.cancelToken.token })
.then(response => {
if (response.data.list) {
this.policy = response.data.list
}
})
.catch(() => {})
},
onInput(event) {
this.checkPolicy(event.target.value)
this.update()
},
onInputConfirm(event) {
this.update()
},
+ prefixed(label) {
+ return (this.prefix != '' ? this.prefix : (this.formPrefix || '')) + label
+ },
update() {
const update = { password: this.password, password_confirmation: this.password_confirmation }
this.$emit('input', {...this.value, ...update})
}
}
}
</script>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Apr 24, 9:58 AM (1 w, 7 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18792711
Default Alt Text
(11 KB)
Attached To
Mode
rK kolab
Attached
Detach File
Event Timeline