Notemod-selfhosted is a database-free, self-hosted memo platform designed to run even on shared hosting.
It stores notes in notemod-data/<DIR_USER>/data.json and provides Web UI sync, API access, clipboard integration, image/file handling, backups, SMTP settings, and optional AES-256-CBC + HMAC encryption.
Overview ・ Features ・ Requirements ・ Installation ・ Initial Setup ・ Directory Structure ・ API ・ Security ・ Backups ・ Links ・ License
This is a fork based on Notemod (upstream) (MIT License), extended as a self-hosted note platform that can run on shared hosting environments.
No database is required, and notemod-data/<DIR_USER>/data.json is used as the single data source.
It is developed to smoothly exchange text, images, and files between Windows PCs and iPhones without relying on external services. It can also serve as an alternative to note services such as simplenote.com.
Single data source:
notemod-data/<DIR_USER>/data.json
- Database-free JSON-based storage
- Memo editing and sync save through the Web UI
- API integration through
api.php,read_api.php,cleanup_api.php, and related endpoints - ClipboardSync integration for sharing text, images, and files between PCs and iPhones
- Image/file storage, listing, deletion, and lock protection
- Optional data encryption with AES-256-CBC + HMAC
- Automatic backups, restore support, and pre-sync-save backups
- Notifications and password reset through
mail()/ SMTP - Authentication security improvements such as CSRF protection, rate limiting, audit logs, and security headers
- Comprehensive security hardening including session regeneration on logout, username collision checks, XSS filtering, CRLF injection prevention, and test directory access protection
- PHP 8.1 or later
- PHP-compatible web server with writable file storage
- No database required
- Shared hosting supported
Verified shared hosting environments: Xserver, Sakura Internet, XREA, InfinityFree
Tested PHP: 8.3.21
Run the dependency-free PHP test suite and HTTP security-header smoke tests locally:
php tests/run.php
bash tests/http_smoke.shThe PHP suite covers configuration defaults, storage paths, trusted-proxy IP and HTTPS detection, canonical URL validation, Unicode password length, media limits, concurrent rate-limit updates, index locking, atomic authentication-config writes, encrypted-data integrity, backup API authentication requirements, mail header CRLF sanitization, rate-limit expiration pruning, username validation and collision detection, Service Worker JSON escaping, and CLI test execution guards. The HTTP smoke test verifies the HTML, API, and unauthenticated image-response security policies against a temporary isolated storage directory.
GitHub Actions runs PHP syntax checks and both test suites on PHP 8.1 through 8.5 for every push and pull request.
- Per-user configuration files
config/<DIR_USER>/config.phpconfig/<DIR_USER>/config.api.phpconfig/<DIR_USER>/auth.php
- Shared mail settings for all users
config/mail.php
- Main data
notemod-data/<DIR_USER>/data.json
- Image index
notemod-data/<DIR_USER>/image_index.json
- File index
notemod-data/<DIR_USER>/file_index.json
- Authentication email address
- Required in
setup_auth.php - Saved as
EMAILinauth.php
- Required in
- Password reset
forgot_password.phpreset_password.phpconfig/<DIR_USER>/password_reset.json
- Encryption
DATA_ENCRYPTION_ENABLEDDATA_ENCRYPTION_KEYdata.jsoncan be encrypted with AES-256-CBC + HMAC
- Session retention period
SESSION_COOKIE_LIFETIME- Can be changed from
log_settings.php
- Mail sending
- Supports both
mail()and SMTP - Centrally managed by the shared mail sending foundation in
auth_common.php
- Supports both
- Backup naming
- Plaintext:
data.json.bak-YYYYMMDD-HHMMSS - Encrypted:
data.enc.json.bak-YYYYMMDD-HHMMSS
- Plaintext:
- Pre-sync-save backup settings
SYNC_PRE_SAVE_BACKUP_ENABLEDSYNC_PRE_SAVE_BACKUP_PRUNE_ENABLED- Can control pre-sync-save backups in the Web UI and pruning old backups immediately before that
- Media lock
- Each item in
file_index.json/image_index.jsonstoreslock: true/false truemeans locked,falsemeans unlocked
- Each item in
- Authentication-related security enhancements
- security headers
- CSRF protection
- rate limiting for login / forgot password / reset password
- audit log
- session regeneration, CSRF token rotation, and cookie clearing on logout and credential change
- username collision and control-character validation
- mail header / SMTP CRLF injection protection
- automatic garbage collection for expired rate-limit buckets
- test suite directory protection via
.htaccessand CLI-only guards
- Token exposure reduction
setup_auth.phpno longer shows API tokens in plain textclipboard_sync.phpuses masked-by-default + temporary revealmedia_files.phpwas changed to a server-side relay design without exposing tokens to the browser
- XSS and template protection
- complete stripping of dangerous HTML elements (
<script>,<style>,<iframe>,<object>,<embed>) and their contents in note rendering - URL protocol validation (
http:,https:,mailto:) andrel="noopener noreferrer"for inserted links - safe JSON escaping (
JSON_HEX_*) in inline scripts and Service Worker configurations
- complete stripping of dangerous HTML elements (
- Backup security
api/cleanup_api.php?action=backup_nowrequires authentication (session, Bearer token, orX-Notemod-Token) to prevent unauthenticated backup generation DoS
- Unified API token authentication across all endpoints (
read_api.php,api.php,cleanup_api.php,image_api.php,append_api.php,search_api.php,journal_api.php) viaAuthorization: Bearer <TOKEN>andX-Notemod-Token: <TOKEN>headers while maintaining backward compatibility - Added automatic request URL fallback for internal server-side API calls in
media_files.phpwhen environment variables are unset, and enabled configuring base URLs inconfig/config.php - Enforced authentication on
cleanup_api.php?action=backup_nowto prevent unauthenticated backup DoS - Strengthened account and logout security: username uniqueness and control-character validation, full cookie clearing, CSRF token rotation, and session regeneration on logout
- Added email header / SMTP CRLF injection protection and automatic garbage collection for expired rate-limit buckets
- Hardened Web UI and Service Worker against XSS: stripped dangerous HTML blocks, safely escaped inline scripts with
JSON_HEX_*, and enforced safe link protocols - Secured test suite with
.htaccessand blocked direct Web execution of test runners - Fixed configuration file generation in
setup_auth.phpto prevent corruption from regex backreferences - Expanded automated test coverage in
tests/run.phpto 23 comprehensive security and integration tests
- Added
NM_STORAGE_ROOTand updated.gitignorefor the per-user storage layout, keeping runtime data and secrets out of version control - Added trusted-proxy-aware client IP and HTTPS detection through
NM_TRUSTED_PROXIES - Replaced URLs derived from the
Hostheader with validatedNM_PUBLIC_BASE_URLand optionalNM_INTERNAL_BASE_URLsettings - Clarified image API authentication and applied private, no-store cache controls to protected responses
- Made rate-limit state, authentication configuration, and media index updates concurrency-safe with locking and atomic writes
- Added application-level upload, image-processing, and request-size limits
- Unified Unicode-aware password length validation, security headers, CSP handling, and shared configuration defaults
- Added dependency-free PHP tests, HTTP security smoke tests, and a PHP 8.1-8.5 GitHub Actions test matrix
- Previously, images did not have an index equivalent to
file_index.json, but v1.4.6 addsimage_index.json - Incrementally updated when images are uploaded
- Regenerated after image deletion or purge
media_files.phpnow builds the image list by prioritizingimage_index.json
- Added
lockto each image and file entry - Stored as a boolean
true= lockedfalse= unlocked
- Default value for new entries is
false
- Added a lock icon to the right of the checkbox for each image and file row
- Each click toggles between
- locked
- unlocked
- The UI was adjusted to a small icon button so it blends into the existing screen
- Images/files with
lock=trueare excluded from deletion targets - Even if they are included in bulk deletion or individual deletion operations, locked items are not deleted
- Unlocked items remain deletable as before
- When
api/cleanup_api.phpregeneratesfile_index.json/image_index.json, it now preserves the existinglockstate if a file with the same name already exists in the old index - This makes lock settings less likely to be lost after cleanup or purge
- Reorganized shared authentication-related security handling mainly in
auth_common.php - Added common security headers to HTML pages
X-Content-Type-Options: nosniffX-Frame-Options: SAMEORIGINReferrer-Policy: same-originCache-Control: no-store, no-cache, must-revalidate, max-age=0Pragma: no-cache
login.phpnow performssession_regenerate_id(true)after successful login- Improved protected pages so security headers are also applied when returning an unauthenticated redirect
- Added CSRF tokens to major form-based pages
- Targets:
login.phpsetup_auth.phpaccount.phplog_settings.phpbak_settings.phpforgot_password.phpreset_password.php- token reveal in
clipboard_sync.php - download / upload / cleanup / lock actions in
media_files.php
- Requests with missing or tampered tokens are rejected
login.phpforgot_password.phpreset_password.php
Short-time repeated attempts are now restricted
- Repeated failed login attempts are limited
- Repeated password reset requests in a short period are limited
- Repeated password reset attempts in a short period are limited
- Required buckets are cleared on successful completion
- Added shared audit log handling to
auth_common.php - Stored in
logs/audit.logunderNM_STORAGE_ROOT(JSON Lines) - Records events such as:
login_successlogin_failedlogin_rate_limitedpassword_reset_requestedpassword_reset_request_rate_limitedpassword_reset_failedpassword_reset_completedpassword_reset_rate_limitedsetup_auth_updated- various operation events from
account/log_settings/bak_settings
- Secret values are not recorded; only minimum necessary differences such as
- changed flags
- from / to
- masked email are stored
- Changed so
EXPECTED_TOKEN/ADMIN_TOKENare not displayed in plain text as existing values - Input fields are shown empty
- Existing tokens are indicated only through placeholders / explanatory text as “configured”
- Leaving the fields blank keeps existing values
- Values are updated only when new input is provided
EXPECTED_TOKEN/ADMIN_TOKENare always masked on initial display- They are fetched from the server and temporarily revealed only when unlocked
- They are automatically re-locked after 10 seconds
- Copy is allowed only while visible
- Copy is disabled while locked
- Added CSRF protection to the
reveal_tokenPOST
- Improved so
EXPECTED_TOKEN/ADMIN_TOKENare not directly exposed to the browser - Image/file upload / cleanup / lock / download are handled through server-side relay processing inside
media_files.phpitself - The frontend operates on a session + CSRF basis
- Improved image URL copy and image copy so tokens are not exposed in URLs
- Added
parse_file_history_jsonl()for restoring display fromfile.json(JSON Lines) history
- Supports all of:
userdir_userusername
- Reorganized the old logic that re-assigned
$_GET['user']later in the file and effectively invalidated the earlier helper-based resolution - This improves image retrieval so
dir_userandusernamebased access works as intended - Image retrieval requires either a logged-in Web UI session for the same user or that user's
EXPECTED_TOKEN - Authenticated image responses use
Cache-Control: private, no-store; resized derivatives may still be cached only on the server under the user's.cachedirectory
- Saving authentication email addresses
- Password reset
- Shared mail sending foundation
- Shared mail settings for all users via
config/mail.php - SMTP settings UI / test sending
append_api.phpsearch_api.phpjournal_api.php- Snapshot normalization before sync save
.txt/.jsonimport support- Countermeasures for stringified
categories/notes SESSION_COOKIE_LIFETIMEsupport- Stronger XSS protection in
index.php - Optional encrypted saving of
data.json - Pre-sync-save backup control in the Web UI
- Improved behavior so that even if the Web UI login session expires after a long idle period, local browser data is less likely to disappear immediately on the spot
- When 401 / 403 is detected during communication with
notemod_sync.php, automatic sync is paused and the screen now clearly indicates that the session has expired and re-login is required - After session expiry, auto load and manual load are conditionally blocked to reduce the risk of local browser data being overwritten by older server-side data
- Adjusted the warning behavior so that a strong warning is shown only when local changes were made after session expiry, and fixed the issue where the red warning could appear repeatedly during normal operation
- After a normal successful sync, the warning-related flags are cleared and the UI returns to the normal state
/index.php
/setup_auth.php
/login.php
/logout.php
/account.php
/forgot_password.php
/reset_password.php
/auth_common.php
/data_crypto.php
/logger.php
/log_settings.php
/bak_settings.php
/media_files.php
/clipboard_sync.php
/notemod_sync.php
/sw.php
/manifest.php
/api/
api.php
read_api.php
cleanup_api.php
image_api.php
append_api.php
search_api.php
journal_api.php
/config/mail.php
/config/<DIR_USER>/
auth.php
config.php
config.api.php
password_reset.json
/notemod-data/<DIR_USER>/
data.json
image_index.json
file_index.json
images/
files/
/logs/<DIR_USER>/
/logs/audit.log
/tests/
.htaccess
http_smoke.sh
rate_limit_worker.php
request_ip_override.php
run.php
- Download or clone this repository.
- Upload the files to the public directory of your server.
- Configure the runtime storage directory as described below. Using a directory outside the public directory is strongly recommended.
- Open
login.phpin your browser. - After creating the first admin user, check SECRET, API token, encryption settings, and related options in
setup_auth.php.
If you are migrating existing data, back up
notemod-data/<DIR_USER>/data.jsonandconfig/<DIR_USER>/before making changes.
Set the NM_STORAGE_ROOT environment variable to an absolute path that PHP can read and write. Notemod then stores config/, notemod-data/, and logs/ under that path instead of under the application directory.
NM_STORAGE_ROOT=/var/lib/notemod
For a new installation, create the directory, grant the PHP process read/write access, and set the environment variable before opening setup_auth.php. For an existing installation:
- Back up the current
config/,notemod-data/, andlogs/directories. - Move all three directories under the new storage root without changing their names or contents.
- Set
NM_STORAGE_ROOTin the PHP-FPM pool, Apache environment, container configuration, or hosting control panel. - Restart or reload the PHP/web server and verify login, note sync, media access, and logging.
The variable must contain an absolute path and must not point to the filesystem root itself. If it is unset, Notemod keeps using the legacy directories inside the application directory for backward compatibility. In that legacy layout, direct HTTP access must be denied by the web-server configuration; the generated .htaccess files only protect Apache-compatible servers.
By default, Notemod uses only REMOTE_ADDR and ignores client-supplied forwarding headers. If Notemod is behind a reverse proxy, set NM_TRUSTED_PROXIES to the proxy IP addresses or CIDR ranges:
NM_TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8,2001:db8:1234::/48
Only when REMOTE_ADDR matches this list does Notemod inspect X-Forwarded-For and X-Forwarded-Proto. It evaluates the address chain from right to left and selects the first address that is not a trusted proxy. A validated X-Forwarded-Proto: https value is also used for secure cookies and HTTPS state detection. Configure the proxy to replace incoming forwarding headers with validated values, and keep the trusted ranges as narrow as possible. Leave the variable unset when no reverse proxy is used.
Set NM_PUBLIC_BASE_URL to the canonical URL where Notemod is available. Include the installation subdirectory, if any, and do not include a query or fragment:
NM_PUBLIC_BASE_URL=https://notes.example.com/notemod
Password-reset links use only this configured URL and are never generated from the request Host header. If it is not configured, reset mail delivery is skipped and the omission is recorded in logs/forgot_password.log without exposing account existence to the requester.
The media screen also uses this URL for its server-side API calls. If the public address is not reachable from the server itself, set a separate internal address:
NM_INTERNAL_BASE_URL=http://127.0.0.1/notemod
NM_INTERNAL_BASE_URL is optional and falls back to NM_PUBLIC_BASE_URL. Both values must be absolute http or https URLs without credentials, query parameters, fragments, or parent-directory segments. API URLs shown in the browser are completed using the configured public URL, or the browser's own origin when it is unset.
Both NM_PUBLIC_BASE_URL and NM_INTERNAL_BASE_URL can also be configured in config/<DIR_USER>/config.php (e.g. 'NM_PUBLIC_BASE_URL' => 'https://notes.example.com/notemod'). Furthermore, internal server-side API calls in media_files.php automatically fall back to the current web request URL if these variables are unset, allowing drag-and-drop uploads and cleanups to work out of the box on shared hosts without environment variable access (only password reset emails require an explicit base URL to guard against host header poisoning).
Upload the full repository contents to your public folder.
Access setup_auth.php / index.php and complete the initial setup.
setup_auth.php manages the following settings:
- Initial user
- Password
- Authentication email address
- Initial pre-sync-save backup settings if needed
- API token-related settings if needed
Main files automatically generated as needed:
config/<DIR_USER>/auth.phpconfig/<DIR_USER>/config.phpconfig/<DIR_USER>/config.api.phpconfig/<DIR_USER>/.htaccessnotemod-data/<DIR_USER>/data.jsonnotemod-data/<DIR_USER>/.htaccesslogs/<DIR_USER>/.htaccessapi/.htaccesstests/.htaccess
config/mail.php is created when SMTP settings are saved.
image_index.json / file_index.json are generated and updated when images or files are added.
config/<DIR_USER>/config.php
Main keys:
SECRETTIMEZONEDEBUGLOGGER_FILE_ENABLEDLOGGER_NOTEMOD_ENABLEDLOGGER_FILE_MAX_LINESLOGGER_NOTEMOD_MAX_LINESIP_ALERT_ENABLEDIP_ALERT_TOIP_ALERT_FROMIP_ALERT_SUBJECTIP_ALERT_IGNORE_BOTSIP_ALERT_IGNORE_IPSIP_ALERT_STORESESSION_COOKIE_LIFETIMEMAX_IMAGE_UPLOAD_BYTESMAX_FILE_UPLOAD_BYTESMAX_IMAGE_DIMENSIONMAX_IMAGE_PIXELSMAX_RESIZE_DIMENSIONMAX_RESIZE_PIXELSDATA_ENCRYPTION_ENABLEDDATA_ENCRYPTION_KEYSYNC_PRE_SAVE_BACKUP_ENABLEDSYNC_PRE_SAVE_BACKUP_PRUNE_ENABLED
Uploads and image decoding are also limited by the application before files are stored or GD allocates image buffers. Defaults are 10 MiB for images, 25 MiB for other files, 10,000 px / 25 megapixels for source images, and 2,000 px / 4 megapixels for resized images. PHP's upload_max_filesize and post_max_size remain separate limits; the lowest applicable limit wins.
config/<DIR_USER>/config.api.php
Main keys:
EXPECTED_TOKENADMIN_TOKENDATA_JSONDEFAULT_COLORCLEANUP_BACKUP_ENABLEDCLEANUP_BACKUP_SUFFIXCLEANUP_BACKUP_KEEP
config/<DIR_USER>/auth.php
Main keys:
USERNAMEDIR_USERPASSWORD_HASHEMAILUPDATED_ATPASSWORD_RESET_TOKENPASSWORD_RESET_TOKEN_HASHPASSWORD_RESET_TOKEN_EXPIRES_AT
config/mail.php
Main keys:
MAIL_TRANSPORTSMTP_ENABLEDSMTP_HOSTSMTP_PORTSMTP_ENCRYPTIONSMTP_AUTHSMTP_USERNAMESMTP_PASSWORDSMTP_FROMSMTP_FROM_NAMESMTP_FALLBACK_TO_MAILUPDATED_AT
- You can run Back up now from
bak_settings.php - You can also run it via
api/cleanup_api.php?action=backup_now(requires authentication: session or API token)
- If
CLEANUP_BACKUP_ENABLEDis enabled, a backup is created before dangerous cleanup operations CLEANUP_BACKUP_KEEPcontrols how many backups are kept
- If
SYNC_PRE_SAVE_BACKUP_ENABLEDis enabled, a backup is created immediately before actual save during Web UI sync save - If
SYNC_PRE_SAVE_BACKUP_PRUNE_ENABLEDis also enabled, old backups are pruned immediately before that CLEANUP_BACKUP_KEEPis used to determine how many old backups are kept- The pruning logic is the same as Delete to keep latest n backups in
bak_settings.php
- Backup lists are sorted in newest-first order (by file modification time)
- The newest
nfiles are kept, and the rest are deleted - If
n=0, all are deleted - Plaintext and encrypted backups are judged together
- An index that keeps the list of currently existing files
- Incrementally updated when files are added by
api/api.php - Regenerated after deletion or purge by
api/cleanup_api.php - Each item has
lockto preserve deletion-exclusion state
- An index that keeps the list of currently existing images
- Incrementally updated when images are added by
api/api.php - Regenerated after deletion or purge by
api/cleanup_api.php - Each item has
lockto preserve deletion-exclusion state
- If
true, the image / file is locked - Locked items are excluded from deletion targets
- If
false, the item is unlocked and deletable as before
If possible, configure BASIC authentication for api/.
If BASIC authentication is not available, you can still achieve a reasonable level of security by operating with Web UI authentication using setup_auth.php, login.php, and logout.php.
The following additional protections are applied:
- response-type-specific security headers for HTML, API/text, and binary responses, including a Content Security Policy (CSP)
- centralized common configuration defaults shared by setup, settings screens, APIs, and logging
- CSRF protection
- rate limiting for
login.php/forgot_password.php/reset_password.php - shared/exclusive file locking and atomic replacement for concurrent rate-limit state updates
- per-index exclusive locking from read through atomic replacement for concurrent upload, media-lock, and cleanup updates
- one shared 10-character Unicode-aware minimum-password check for initial setup, account changes, and password resets
- audit logging
- session regeneration on successful login via
session_regenerate_id(true) - reduced plain-text exposure of API tokens in
setup_auth.php,clipboard_sync.php, andmedia_files.php - session regeneration, CSRF token rotation, and cookie clearing on logout and credential changes
- username collision and control-character validation on account changes
- CRLF injection prevention in mail notifications and automatic pruning of expired rate-limit buckets
- XSS prevention in Web UI and Service Worker: dangerous tag and content stripping in HTML sanitization, secure link protocol enforcement, and JSON escaping in inline scripts
- authentication required for manual backups via
api/cleanup_api.php?action=backup_now - access restriction on the
tests/directory with.htaccessand CLI-only execution guards
- When
DATA_ENCRYPTION_ENABLEDistrue,data.jsonis stored encrypted - Export is always plain JSON
- If you lose the encryption key, you cannot decrypt the data
SMTP_PASSWORDinconfig/mail.phpis stored in plain text- Prefer an
NM_STORAGE_ROOToutside the public directory so thatconfig/mail.phpcannot be served directly
- Path:
<NM_STORAGE_ROOT>/logs/audit.log(logs/audit.logwhenNM_STORAGE_ROOTis unset) - Format: JSON Lines
- Secret values such as passwords, API tokens, SECRET, and SMTP password are not recorded
All API endpoints (api.php, read_api.php, cleanup_api.php, image_api.php, append_api.php, search_api.php, journal_api.php) support the following authentication methods:
- HTTP Headers:
Authorization: Bearer <TOKEN>orX-Notemod-Token: <TOKEN>(recommended) - POST parameter:
token=<TOKEN>(form-data or request body)
This ensures secure and seamless communication with external tools such as ClipboardSync.
- Add text
- Upload images
- Upload files
- Auto-create categories if needed
- Update
note_latest.json - Update
image_index.json/file_index.json
- Read-only
latest_notelatest_clip_typelatest_imagelatest_file
When calling the API, using
user=<DIR_USER>is recommended
- Delete by category
dry_run- Delete backups
- Delete logs
- Bulk delete images / files
- Regenerate
image_index.json/file_index.json - Update media lock state
- Manual backup creation (
action=backup_now) - Requires authentication for all operations, including backups (supports Web UI session, Bearer token, or
X-Notemod-Tokenheader)
- Serve authenticated images
- Simple resizing
- Supports user resolution via
user/dir_user/username - Accepts a same-user Web UI session,
Authorization: Bearer <EXPECTED_TOKEN>, orX-Notemod-Token: <EXPECTED_TOKEN> - Does not accept API tokens in the URL query string
- Returns
Cache-Control: private, no-store, no-cache, must-revalidate, max-age=0so browsers and shared proxies do not retain protected image responses - Keeps resized derivatives in a server-side
.cachedirectory; this disk cache is never a public HTTP cache policy
Example:
curl -H 'Authorization: Bearer YOUR_EXPECTED_TOKEN' \
'https://notes.example.com/notemod/api/image_api.php?user=YOUR_DIR_USER&file=photo.png' \
--output photo.png- Append to the end of an existing note
- Target can be specified by
category + noteortarget_note_id - Insert date / time / datetime / category name / note name
prefix/suffixdry_run- Returns text/plain when
prettyis omitted
- Search category names / note titles / note bodies
typeqmatchlimitsnippetcategoryfilter- Retrieve
note_id
- Date-based / monthly / weekly / fixed-note append
mode=date|month|week|fixedtemplate=journal|log|plain|task- Auto-create categories / notes
- Insert weekday
dry_run- Returns text/plain when
prettyis omitted
What log_settings.php handles:
- File log ON/OFF
- Notemod Logs category log ON/OFF
SESSION_COOKIE_LIFETIME- Display of
session.gc_maxlifetime - IP access notification settings
- Reflect authentication email button
- SMTP settings (expand/collapse)
- SMTP test send
What bak_settings.php handles:
- Enable pre-sync-save backup (SYNC_PRE_SAVE_BACKUP_ENABLED)
- Prune old backups before sync save (SYNC_PRE_SAVE_BACKUP_PRUNE_ENABLED)
- Enable backup (CLEANUP_BACKUP_ENABLED)
- Keep latest n backups / n=0 deletes all (CLEANUP_BACKUP_KEEP)
- Back up now
- Restore backups
What media_files.php handles:
- Image list
- File list
- Media deletion
- Lock / unlock toggle
- Excluding locked media from deletion
- Upload / cleanup / lock / download through a relay design that does not expose tokens to the browser
What clipboard_sync.php handles:
- ClipboardSync download links
- API URL copy
- Initially masked API token display
- Temporary reveal for 10 seconds only when unlocked
- Copy only while visible
- CSRF-protected token reveal
Description:
This is the browser-side retention period. Depending on server-side settings, login may expire earlier.
- APIs and cleanup are expected to always reference
config/<DIR_USER>/config.api.php - Do not revert to the old
/config/config.api.php-based design - In
config.php,SYNC_PRE_SAVE_BACKUP_ENABLEDSYNC_PRE_SAVE_BACKUP_PRUNE_ENABLEDare for controlling pre-sync-save backups in the Web UI
- In
config.api.php,CLEANUP_BACKUP_ENABLEDCLEANUP_BACKUP_KEEPare for cleanup backup control and keep-count control
config/mail.phpis shared by all users- If you use SMTP, verify consistency between the sender address, SPF / DKIM, and SMTP authentication
lockinfile_index.json/image_index.jsonis used to preserve deletion-exclusion state for each media item- Items with
lock=trueare excluded from cleanup and deletion operations inmedia_files.php setup_auth.phpdoes not show existing API tokens in plain textclipboard_sync.php/media_files.phpare designed not to directly expose API token values to the browser- Even when handling broken legacy
data.jsonformats, the current code is intended to normalize as much as possible before saving append_api.php/search_api.php/journal_api.phpare designed to return human-readable text/plain equivalent topretty=2when unspecifiedapi/cleanup_api.phprequires authentication (Web UI session, Bearer token, orX-Notemod-Token) for all operations includingaction=backup_nowto prevent unauthorized resource consumptiontests/directory is protected with.htaccessand CLI-only guards to deny direct web access
This project is released under the MIT License.
The upstream Notemod project is also released under the MIT License.