Skip to content

Commit 67054bb

Browse files
authored
release(v3.1.1): OIDC env overrides + configurable resumable chunk size + clearer startup logs (closes #86, closes #87, closes #90)
- config: allow env overrides for OIDC knobs (auto-create, group claim, admin group, Pro group prefix) - uploads: add configurable Resumable.js chunk size (Admin + siteConfig) and honor it in upload.js - uploads: improve relative-path folder uploads and remote staging/cleanup for non-local sources - admin: add settings search + smoother section open/close animations - admin: restrict Pro license actions to the registered/primary admin user - remote storage: add FR_REMOTE_DIR_MARKER to preserve empty dirs; skip Trash on Google Drive sources - UX: clearer “FileRise startup complete” log line + better long-running delete/restore/loading feedback Closes #86 Closes #87 Closes #90
1 parent 4dd517a commit 67054bb

19 files changed

Lines changed: 1455 additions & 219 deletions

CHANGELOG.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,67 @@
11
# Changelog
22

3+
## Changes 01/17/2026 (v3.1.1)
4+
5+
`release(v3.1.1): OIDC env overrides + configurable resumable chunk size + clearer startup logs (closes #86, closes #87, closes #90)`
6+
7+
**Commit message**
8+
9+
```text
10+
release(v3.1.1): OIDC env overrides + configurable resumable chunk size + clearer startup logs (closes #86, closes #87, closes #90)
11+
12+
- config: allow env overrides for OIDC knobs (auto-create, group claim, admin group, Pro group prefix)
13+
- uploads: add configurable Resumable.js chunk size (Admin + siteConfig) and honor it in upload.js
14+
- uploads: improve relative-path folder uploads and remote staging/cleanup for non-local sources
15+
- admin: add settings search + smoother section open/close animations
16+
- admin: restrict Pro license actions to the registered/primary admin user
17+
- remote storage: add FR_REMOTE_DIR_MARKER to preserve empty dirs; skip Trash on Google Drive sources
18+
- UX: clearer “FileRise startup complete” log line + better long-running delete/restore/loading feedback
19+
20+
Closes #86
21+
Closes #87
22+
Closes #90
23+
```
24+
25+
**Added**
26+
27+
- **OIDC env overrides** (in addition to config defaults):
28+
`FR_OIDC_AUTO_CREATE`, `FR_OIDC_GROUP_CLAIM`, `FR_OIDC_ADMIN_GROUP`, `FR_OIDC_PRO_GROUP_PREFIX`.
29+
- **Upload tuning (Admin):** “Resumable chunk size (MB)” (0.5–100 MB).
30+
Exported via siteConfig so the frontend can size chunks dynamically.
31+
- **Remote folder marker:** `FR_REMOTE_DIR_MARKER` (default: `.filerise_keep`) to preserve empty remote folders (S3-style prefix backends).
32+
- **Admin settings search:** quick filter for sections/settings in the Admin panel UI.
33+
34+
**Changed**
35+
36+
- **Resumable uploads honor configured chunk size** (used by file picker + drag/drop when Resumable is available).
37+
- **Upload handling for folder paths**:
38+
- validates and sanitizes `resumableRelativePath` / `relativePath`
39+
- supports subfolder uploads more consistently
40+
- remote sources stage chunks in meta root (`uploadtmp/`) and push via adapter, then cleanup temp folders
41+
- **Admin Pro license visibility/actions** are restricted to the **primary/registered admin** (first admin in `users.txt` order).
42+
- **Remote deletes / Trash behavior**:
43+
- Google Drive sources skip Trash (deletes are permanent)
44+
- remote folder “empty checks” ignore the marker file
45+
- **Docker startup log clarity**:
46+
- `start.sh` prints a “startup complete” line and clarifies that further output is Apache logs.
47+
48+
**Fixed**
49+
50+
- **#86:** OIDC behavior is now controllable via environment variables (no code/config edits required).
51+
- **#87:** Resumable chunk size is now configurable to fit proxy limits (e.g., tunnels/CDNs).
52+
- **#90:** Clearer startup output + better guidance for collecting logs.
53+
- **UI responsiveness / long operations**
54+
- “Deleting…” busy states for file/folder delete confirmations and Trash restore/delete actions
55+
- “Still loading…” toast for slow remote listings, with a fallback if a folder no longer exists
56+
57+
**Notes**
58+
59+
- `FR_REMOTE_DIR_MARKER` is best-effort and primarily intended for remote backends that treat directories as prefixes (e.g., S3).
60+
- Google Drive sources do not support Trash semantics in the adapter; the UI notes this and deletes are permanent.
61+
- Some Admin Panel strings still fall back to English; translations will continue to improve over time.
62+
63+
---
64+
365
## Changes 01/16/2026 (v3.1.0)
466

567
`release(v3.1.0): default language + portal i18n + ffmpeg path config (closes #88, closes #89)`

config/config.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
if (!defined('DEFAULT_VIEW_OWN_ONLY')) define('DEFAULT_VIEW_OWN_ONLY', false);
4646
define('FOLDER_OWNERS_FILE', META_DIR . 'folder_owners.json');
4747
define('ACL_INHERIT_ON_CREATE', true);
48+
// Hidden file used to preserve empty remote folders (S3 prefixes, etc.).
49+
if (!defined('FR_REMOTE_DIR_MARKER')) define('FR_REMOTE_DIR_MARKER', '.filerise_keep');
4850
// ONLYOFFICE integration overrides (uncomment and set as needed)
4951
/*
5052
define('ONLYOFFICE_ENABLED', false);
@@ -63,23 +65,39 @@
6365

6466
// Auto-create users from OIDC when no users.txt match.
6567
if (!defined('FR_OIDC_AUTO_CREATE')) {
66-
define('FR_OIDC_AUTO_CREATE', true);
68+
$envVal = getenv('FR_OIDC_AUTO_CREATE');
69+
if ($envVal !== false && $envVal !== '') {
70+
$val = strtolower(trim((string)$envVal));
71+
define('FR_OIDC_AUTO_CREATE', in_array($val, ['1', 'true', 'yes', 'on'], true));
72+
} else {
73+
define('FR_OIDC_AUTO_CREATE', true);
74+
}
6775
}
6876

6977
// Claim that contains IdP groups/roles (typical: "groups" or "roles").
7078
if (!defined('FR_OIDC_GROUP_CLAIM')) {
71-
define('FR_OIDC_GROUP_CLAIM', 'groups');
79+
$envVal = getenv('FR_OIDC_GROUP_CLAIM');
80+
define(
81+
'FR_OIDC_GROUP_CLAIM',
82+
($envVal !== false && trim((string)$envVal) !== '') ? trim((string)$envVal) : 'groups'
83+
);
7284
}
7385

7486
// Name of an IdP group that should be treated as "FileRise admin".
7587
if (!defined('FR_OIDC_ADMIN_GROUP')) {
76-
define('FR_OIDC_ADMIN_GROUP', 'filerise-admins');
88+
$envVal = getenv('FR_OIDC_ADMIN_GROUP');
89+
if ($envVal !== false) {
90+
define('FR_OIDC_ADMIN_GROUP', trim((string)$envVal));
91+
} else {
92+
define('FR_OIDC_ADMIN_GROUP', 'filerise-admins');
93+
}
7794
}
7895

7996
// Prefix for IdP groups that should map into FileRise Pro groups.
8097
// Example: IdP group "frp_clients_acme" → Pro group "clients_acme".
8198
if (!defined('FR_OIDC_PRO_GROUP_PREFIX')) {
82-
define('FR_OIDC_PRO_GROUP_PREFIX', '');
99+
$envVal = getenv('FR_OIDC_PRO_GROUP_PREFIX');
100+
define('FR_OIDC_PRO_GROUP_PREFIX', ($envVal !== false) ? trim((string)$envVal) : '');
83101
}
84102
// Optional env/constant override: if set, it wins; if not set, UI setting is used.
85103
if (!defined('FR_OIDC_ALLOW_DEMOTE')) {

public/css/styles.css

Lines changed: 221 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,16 @@ body.dark-mode #restoreFilesModal .restore-empty{color: var(--fr-muted-dark,#aaa
441441
font-weight:600;
442442
box-shadow:0 1px 2px rgba(0,0,0,.08);
443443
transition: background-color var(--filr-transition-fast,150ms ease-out), transform var(--filr-transition-fast,150ms ease-out), box-shadow var(--filr-transition-fast,150ms ease-out);}
444+
#restoreFilesModal .restore-btn[aria-busy="true"]{cursor: wait;}
445+
#restoreFilesModal .restore-btn[aria-busy="true"]::after{content:"";
446+
width:14px; height:14px;
447+
border-radius:50%;
448+
border:2px solid currentColor;
449+
border-right-color: transparent;
450+
display:inline-block;
451+
margin-left:4px;
452+
animation: filr-spin .8s linear infinite;}
453+
#restoreFilesModal .restore-btn[aria-busy="true"] .material-icons{opacity:0.6;}
444454
#restoreFilesModal .restore-btn .material-icons{font-size:20px;}
445455
#restoreFilesModal .restore-btn:hover{transform: translateY(-1px); background: #ffffff; box-shadow:0 6px 14px rgba(0,0,0,.12);}
446456
body.dark-mode #restoreFilesModal .restore-btn,body.dark-mode #deleteTrashSelectedBtn{background: var(--fr-surface-dark,#212121); color:#f1f1f1; border-color: var(--fr-border-dark,#303030);}
@@ -1331,7 +1341,7 @@ label{font-size: 0.9rem;}
13311341
}
13321342
#viewOptionsPopover input[type=range]{
13331343
flex:1;
1334-
accent-color: var(--filr-accent-500,#0d6efd);
1344+
13351345
}
13361346
#viewOptionsPopover .vo-value{
13371347
min-width:42px;
@@ -2943,6 +2953,171 @@ body.dark-mode #decreaseFont:not(:disabled):hover,body.dark-mode #increaseFont:n
29432953

29442954
.section-content { display:none; margin-left:20px; margin-top:8px; margin-bottom:8px; }
29452955

2956+
#adminPanelModal .section-header {
2957+
background: linear-gradient(180deg, rgba(15, 23, 42, 0.05), rgba(15, 23, 42, 0.02));
2958+
border: 1px solid rgba(15, 23, 42, 0.08);
2959+
padding: 8px 12px 8px 22px;
2960+
font-weight: 600;
2961+
text-transform: uppercase;
2962+
letter-spacing: 0.08em;
2963+
font-size: 0.85rem;
2964+
position: relative;
2965+
margin-top: 12px;
2966+
color: #111827;
2967+
transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
2968+
}
2969+
#adminPanelModal .section-header:hover {
2970+
background: rgba(15, 23, 42, 0.04);
2971+
border-color: rgba(15, 23, 42, 0.16);
2972+
transform: translateY(-1px);
2973+
}
2974+
#adminPanelModal .section-header:not(.collapsed) {
2975+
background: rgba(59, 130, 246, 0.06);
2976+
border-color: rgba(59, 130, 246, 0.35);
2977+
box-shadow: 0 6px 14px rgba(15, 23, 42, 0.08);
2978+
}
2979+
#adminPanelModal .section-header:not(.collapsed)::before {
2980+
content: "";
2981+
position: absolute;
2982+
left: 8px;
2983+
top: 8px;
2984+
bottom: 8px;
2985+
width: 3px;
2986+
border-radius: 999px;
2987+
background: linear-gradient(180deg, rgba(37, 99, 235, 0.9), rgba(96, 165, 250, 0.9));
2988+
}
2989+
#adminPanelModal .section-header .material-icons { color: #475569; }
2990+
body.dark-mode #adminPanelModal .section-header {
2991+
background: rgba(255, 255, 255, 0.05);
2992+
border-color: rgba(255, 255, 255, 0.08);
2993+
color: #f1f5f9;
2994+
}
2995+
body.dark-mode #adminPanelModal .section-header:hover {
2996+
background: rgba(255, 255, 255, 0.08);
2997+
}
2998+
body.dark-mode #adminPanelModal .section-header:not(.collapsed) {
2999+
background: rgba(96, 165, 250, 0.18);
3000+
border-color: rgba(96, 165, 250, 0.35);
3001+
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.45);
3002+
}
3003+
body.dark-mode #adminPanelModal .section-header:not(.collapsed)::before {
3004+
background: linear-gradient(180deg, rgba(148, 197, 255, 0.95), rgba(96, 165, 250, 0.95));
3005+
}
3006+
body.dark-mode #adminPanelModal .section-header .material-icons { color: #cbd5f5; }
3007+
3008+
#adminPanelModal .section-content {
3009+
display: none;
3010+
margin: 8px 0 12px;
3011+
padding: 12px 14px;
3012+
border-radius: 12px;
3013+
border: 1px solid rgba(15, 23, 42, 0.06);
3014+
background: #ffffff;
3015+
box-shadow: 0 4px 10px rgba(15, 23, 42, 0.04);
3016+
opacity: 0;
3017+
transform: translateY(-4px);
3018+
transition: opacity 160ms ease, transform 160ms ease;
3019+
}
3020+
#adminPanelModal .section-content.is-open {
3021+
opacity: 1;
3022+
transform: translateY(0);
3023+
}
3024+
#adminPanelModal .section-content.is-closing {
3025+
opacity: 0;
3026+
transform: translateY(-4px);
3027+
}
3028+
body.dark-mode #adminPanelModal .section-content {
3029+
background: #232323;
3030+
border-color: rgba(255, 255, 255, 0.08);
3031+
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45);
3032+
}
3033+
3034+
#adminPanelModal .admin-panel-header {
3035+
display: flex;
3036+
align-items: center;
3037+
justify-content: space-between;
3038+
gap: 12px;
3039+
padding-right: 42px;
3040+
margin-bottom: 6px;
3041+
}
3042+
#adminPanelModal .admin-panel-header h3 {
3043+
margin: 0;
3044+
font-weight: 600;
3045+
display: flex;
3046+
flex-wrap: wrap;
3047+
align-items: center;
3048+
gap: 6px;
3049+
}
3050+
#adminPanelModal .admin-panel-actions {
3051+
display: flex;
3052+
align-items: center;
3053+
gap: 8px;
3054+
}
3055+
#adminPanelModal .admin-search-toggle {
3056+
display: inline-flex;
3057+
align-items: center;
3058+
gap: 6px;
3059+
border-radius: 999px;
3060+
padding: 4px 10px;
3061+
border: 1px solid rgba(15, 23, 42, 0.12);
3062+
background: #fff;
3063+
color: #111;
3064+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
3065+
transition: background 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
3066+
}
3067+
#adminPanelModal .admin-search-toggle .material-icons { font-size: 18px; }
3068+
#adminPanelModal .admin-search-toggle:hover {
3069+
background: #f8fafc;
3070+
}
3071+
#adminPanelModal .admin-search-toggle.is-active {
3072+
border-color: rgba(37, 99, 235, 0.45);
3073+
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.12);
3074+
}
3075+
#adminPanelModal .admin-search-toggle-label {
3076+
font-size: 12px;
3077+
font-weight: 600;
3078+
letter-spacing: 0.02em;
3079+
}
3080+
#adminPanelModal .admin-search-wrap {
3081+
margin: 6px 0 12px;
3082+
padding: 8px 12px;
3083+
border-radius: 12px;
3084+
border: 1px solid rgba(15, 23, 42, 0.08);
3085+
background: rgba(15, 23, 42, 0.03);
3086+
overflow: hidden;
3087+
max-height: 180px;
3088+
transition: max-height 200ms ease, opacity 200ms ease, transform 200ms ease, margin 200ms ease, padding 200ms ease, border-color 200ms ease;
3089+
}
3090+
#adminPanelModal .admin-search-wrap.is-collapsed {
3091+
max-height: 0;
3092+
opacity: 0;
3093+
transform: translateY(-6px);
3094+
margin: 0;
3095+
padding-top: 0;
3096+
padding-bottom: 0;
3097+
border-color: transparent;
3098+
}
3099+
body.dark-mode #adminPanelModal .admin-search-toggle {
3100+
background: #2a2a2a;
3101+
color: #e5e7eb;
3102+
border-color: rgba(255, 255, 255, 0.12);
3103+
box-shadow: none;
3104+
}
3105+
body.dark-mode #adminPanelModal .admin-search-toggle:hover {
3106+
background: #333;
3107+
}
3108+
body.dark-mode #adminPanelModal .admin-search-toggle.is-active {
3109+
border-color: rgba(147, 197, 253, 0.45);
3110+
box-shadow: 0 0 0 2px rgba(147, 197, 253, 0.12);
3111+
}
3112+
body.dark-mode #adminPanelModal .admin-search-wrap {
3113+
background: rgba(255, 255, 255, 0.04);
3114+
border-color: rgba(255, 255, 255, 0.08);
3115+
}
3116+
@media (max-width: 720px) {
3117+
#adminPanelModal .admin-search-toggle-label { display: none; }
3118+
#adminPanelModal .admin-panel-header { gap: 8px; }
3119+
}
3120+
29463121
#adminPanelModal .editor-close-btn,
29473122
#closeRestoreModal {
29483123
position:absolute; top:10px; right:10px; display:flex; align-items:center; justify-content:center;
@@ -2957,6 +3132,50 @@ body.dark-mode #decreaseFont:not(:disabled):hover,body.dark-mode #increaseFont:n
29573132

29583133
.action-row { display:flex; justify-content:space-between; margin-top:15px; }
29593134

3135+
#adminPanelModal .action-row {
3136+
position: sticky;
3137+
bottom: 0;
3138+
z-index: 2;
3139+
margin-top: 18px;
3140+
padding: 10px 0 6px;
3141+
gap: 6px;
3142+
justify-content: flex-end;
3143+
background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.9) 35%, rgba(255, 255, 255, 1));
3144+
border-top: 1px solid rgba(15, 23, 42, 0.08);
3145+
}
3146+
#adminPanelModal .action-row .btn {
3147+
border-radius: 999px;
3148+
min-width: 110px;
3149+
box-shadow: none;
3150+
transform: none;
3151+
transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
3152+
}
3153+
#adminPanelModal .action-row .btn:hover,
3154+
#adminPanelModal .action-row .btn:focus-visible,
3155+
#adminPanelModal .action-row .btn:active {
3156+
box-shadow: none;
3157+
transform: none;
3158+
opacity: 1;
3159+
filter: brightness(1.02);
3160+
}
3161+
#adminPanelModal .action-row .btn.btn-primary {
3162+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.16);
3163+
}
3164+
#adminPanelModal .action-row .btn.btn-primary:hover,
3165+
#adminPanelModal .action-row .btn.btn-primary:focus-visible {
3166+
transform: translateY(-1px);
3167+
box-shadow: 0 10px 22px rgba(0, 140, 180, 0.28);
3168+
filter: brightness(1.04);
3169+
}
3170+
#adminPanelModal .action-row .btn.btn-primary:active {
3171+
transform: translateY(0);
3172+
box-shadow: 0 4px 12px rgba(0, 140, 180, 0.22);
3173+
}
3174+
body.dark-mode #adminPanelModal .action-row {
3175+
background: linear-gradient(180deg, rgba(35, 35, 35, 0), rgba(35, 35, 35, 0.92) 35%, rgba(35, 35, 35, 1));
3176+
border-top-color: rgba(255, 255, 255, 0.08);
3177+
}
3178+
29603179
/* ---------- Folder access editor ---------- */
29613180
.folder-access-toolbar {
29623181
display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:8px 0 6px;
@@ -3979,7 +4198,7 @@ body.dark-mode #adminPanelModal .sources-hint-btn::after{background:var(--fr-sur
39794198

39804199
/* Give every admin section a little breathing room at the top */
39814200
#adminPanelModal .section-content {
3982-
padding-top: 10px;
4201+
padding-top: 12px;
39834202
}
39844203
#adminPanelModal .admin-subsection-title {
39854204
font-weight: 600;

0 commit comments

Comments
 (0)