Data room portal – access chain, sign-in and viewing
The portal's access chain checked on every request, sign-in, persistent session and invitation token, and the viewing, preview, search and quick link endpoints.
Overview
A separate password-protected portal page where documents of folders shared on the admin side can be viewed, searched and — if allowed — downloaded with a watermark. Sign-in uses the framework's admin user master. Store-dependent: folders and documents are visible only in the store (subdomain) they are assigned to.
Common access chain
- The user is active (
isUserActive, on every request); session keydocshare_user_id. - The folder is accessible (
accessibleWhere):doc_share.status = 1,date_start <= now < date_expirein Budapest time, the user's own assignment window, and store filtering (doc_share_to_store). - Document:
doc_share_itemmembership,doc.status = 1, content (company) scope from thecompany/company_idrules ofpermission_scope(user, else group; super admin unlimited; no rule means no restriction; an empty allow list means nothing), and document store filtering (doc_to_store). - Every event is written to the audit log (channel
document/portal) with IP address and user agent.
Endpoints
| Endpoint | Behaviour |
|---|---|
document/document | without sign-in only the login box; signed in: left navigation, labels, global search. Without doc_share_id the home page: folder cards, statistics, all accessible documents deduplicated by doc_id (the more favourable download right wins), external web links, total size; with doc_share_id the folder view. Per row type, can_view, can_download (folder AND document downloadable), only controller URLs. For a non-default store the store's name and logo. |
.login, .logout | authenticate(): active user, password_verify; with remember a 30-day persistent token (doc_portal_token, cookie dlbt_portal_remember: secure, httponly, SameSite=Lax). Failures are logged with the user name. Sign-out deletes token and cookie. |
.setpassword, .setpasswordsave | verifyInviteToken() (SHA-256; active, unused, not expired, bound to an active user); nothing leaks for an invalid one. Save: at least 8 characters and match, setUserPassword(), markInviteUsed(), automatic sign-in, logged. Table: user_invite. |
.view | full chain; direct navigation blocked for embeddable types (Sec-Fetch-Dest: document); bytes from storage (local copy, for Drive and OneDrive the doc cache outside the web root); office files converted to PDF via Drive (cached); dynamic watermark for PDF (Dlbtwatermark::pdf: name, ID, date, time, warning text); Content-Disposition: inline; temporary files are deleted |
.gview | for a Drive file, after the chain, a link-based read permission (once per session) and a redirect to the Drive preview; this path does not watermark |
.thumb | images only, w = 240, 480 or 960; ETag and 304; cache with LRU touch; 403 without permission |
.sheet | for a downloadable folder and document a Google copy ("name (online)") with writer/anyone right, written to the doc record; the original does not change |
.search, .searchall | name filter within the folder; global search across all accessible folders, logged with the term and hit count |
.t&t= | quick link without sign-in: doc_token (SHA-256, active, not expired), optional password, dl=1 only for allow_download=1 tokens, proxied bytes, hit counter, logged; invalid → neutral 404; no watermark on this path |
Known limitations
- There is no sign-in attempt limit in the code.
- The
gviewand quick link paths do not watermark.