Compare commits

...
667 Commits
Author SHA1 Message Date
Eric Dubé fc51424f86 Merge pull request #332 from HeyPuter/release-please--branches--main--components--puter.com
chore(main): release 1.0.0
2024-05-24 16:25:34 -04:00
github-actions[bot] 5146dc4981 chore(main): release 2.3.0 2024-05-24 16:22:55 -04:00
Nariman Jelveh 103f9d209d Update README.md 2024-05-23 14:32:24 -07:00
KernelDeimos 4508bfac73 Fix cookie issue 2024-05-23 13:30:02 -04:00
Eric Dubé b15dc316d3 Merge pull request #406 from AtkinsSJ/fs-upload-data-type-error
Explicitly reject invalid types for puter.fs.upload() and .write() payloads
2024-05-22 12:13:24 -04:00
KernelDeimos 1f6a2093fb Disallow negative size values 2024-05-21 18:46:34 -04:00
KernelDeimos 90463a0732 Add support for webhook endpoints 2024-05-21 17:25:28 -04:00
Karan Parmar cc45a08388 updated the github links displayed in the Terminal welcome message 2024-05-19 11:52:26 +01:00
KernelDeimos 8cca067991 Fix 8688ha84v 2024-05-17 22:55:40 -04:00
Eric Dubé 80b763c47c Merge pull request #407 from AtkinsSJ/clean-suggested-apps
fix: Remove null or duplicate app entries from suggest_app_for_fsentry()
2024-05-17 15:46:06 -04:00
Eric Dubé 8786024559 Merge pull request #404 from secondtruth/patch-1
Update de.js
2024-05-17 15:42:02 -04:00
Eric Dubé bbb43f53d0 Merge pull request #403 from Zac0511/patch-3
Update fr.js
2024-05-17 15:39:06 -04:00
KernelDeimos 639e40d355 Phoenix shell deployment update 2024-05-17 13:26:44 -04:00
KernelDeimos f964f06f3f Fix 8688h4bwg 2024-05-17 13:05:13 -04:00
KernelDeimos e4543c5f35 Fix 8688ggu00 (2) 2024-05-17 12:32:16 -04:00
Sam Atkins 6900233c5a fix: Remove null or duplicate app entries from suggest_app_for_fsentry() 2024-05-17 15:34:36 +01:00
Sam Atkins 03fe3b6a0d Reject invalid types for puter.fs.upload() items or .write() data
Previously, this would crash in upload() when trying to iterate the
`entries` array, which is undefined when the `items` parameter is an
unsupported type.
2024-05-17 14:39:31 +01:00
Sam Atkins a9c89cef19 refactor: Reduce boilerplate for returning errors from puter.fs.upload() 2024-05-17 14:39:31 +01:00
Zac0511 340b9202c0 Update fr.js 2024-05-17 14:36:54 +02:00
Zac0511 99ca8755f3 Update fr.js 2024-05-17 14:22:22 +02:00
Zac0511 eaf1e96fa2 Update fr.js 2024-05-17 14:19:19 +02:00
Zac0511 f9b5353058 Update fr.js 2024-05-17 14:15:49 +02:00
Zac0511 e0af914c90 Update fr.js 2024-05-17 14:00:43 +02:00
Zac0511 8f19f4dc5b Update fr.js
Complete rework of the file, completly remade from en.js
2024-05-17 13:58:33 +02:00
Zac0511 5f47e7f0fa Update fr.js
Bug repairing... again
2024-05-17 09:55:25 +02:00
Zac0511 9c39b0453d Update fr.js
Little update for some bugs
2024-05-17 09:16:12 +02:00
Zac0511 545fc103b8 Update fr.js
Complete rework of the file for the latest updates
2024-05-17 09:10:55 +02:00
KernelDeimos c55b1e4680 Remove verification requirement on contact us form 2024-05-16 19:08:51 -04:00
Eric Dubé 297db58e68 Merge pull request #405 from HeyPuter/eric/path-builder
Add path builder
2024-05-16 19:08:56 -04:00
KernelDeimos e3f57ee20e Add path builder 2024-05-16 19:02:58 -04:00
KernelDeimos 5031cea040 Update _default.js for deployment purposes 2024-05-16 18:55:59 -04:00
Eric Dubé 6fe126ad5a Merge pull request #386 from HeyPuter/eric/socket-auth
fix(security): Move token for socket.io to request body
2024-05-16 18:02:12 -04:00
KernelDeimos 49b257ecff fix(security): Move token for socket.io to request body
Currently this commit breaks websocket events and needs to
be updated.
2024-05-16 17:58:44 -04:00
KernelDeimos f042b095f1 Fix 8688gxkuj 2024-05-16 17:25:41 -04:00
Christian Neff 43d0936533 Update de.js
Translated:
- 2FA strings
- Task Manager strings
- 2 other scattered strings
2024-05-16 19:51:42 +02:00
KernelDeimos b68873c5f4 Fix 8688grpf1 2024-05-16 12:48:57 -04:00
Zac0511 e1ae9241af Update fr.js 2024-05-16 18:27:12 +02:00
Zac0511 b6ea37c517 Update fr.js
Since there was a lot of text and menus added, and they were not translated, so i just translated them.
2024-05-16 18:06:21 +02:00
KernelDeimos bee0e19eaf Fix 8688ggu00 2024-05-15 20:59:20 -04:00
Eric Dubé f54657a569 Merge pull request #402 from HeyPuter/eric/email-lock
Add locking to save_account
2024-05-15 18:49:03 -04:00
Eric Dubé 1aa27084d0 Merge pull request #396 from AtkinsSJ/xterm-fix
fix(Terminal): Accept input from Chrome on Android
2024-05-15 18:24:02 -04:00
KernelDeimos 691c8f1436 Add locking to save_account 2024-05-15 18:22:54 -04:00
Eric Dubé b72e5b7e02 Merge pull request #401 from HeyPuter/eric/service-patches
Allow patching services
2024-05-15 15:47:14 -04:00
KernelDeimos c70e378973 Add error id for expired auth tokens 2024-05-15 15:42:00 -04:00
KernelDeimos 21444daefb Add jsdoc comments to registerService and patchService 2024-05-15 15:41:37 -04:00
KernelDeimos 2e0d7361cb Add method to patch services 2024-05-15 15:32:18 -04:00
Eric Dubé 6e0b6d84d2 Merge pull request #400 from AtkinsSJ/fix-apierror-includes
fix: Correct APIError imports
2024-05-15 13:51:04 -04:00
Eric Dubé ec59abe3ae Merge pull request #399 from AtkinsSJ/fix-db-scripts
fix: Add missing file extension to 0009_app-prefix-fix.sql in DB init
2024-05-15 13:45:30 -04:00
Sam Atkins 062e23b5c9 fix: Correct APIError imports
APIError is the only thing exported from its file, so we must not wrap
it in {}.
2024-05-15 17:47:15 +01:00
Sam Atkins a8160a8cdc fix: Add missing file extension to 0009_app-prefix-fix.sql in DB init 2024-05-15 10:18:28 +01:00
KernelDeimos 0b093dd57e Revoke other sessions when password is changed 2024-05-14 19:40:57 -04:00
KernelDeimos 923d5878c3 Prevent enable of 2FA without configure 2024-05-14 17:33:14 -04:00
Eric Dubé 9c5849fbce Merge pull request #397 from HeyPuter/eric/anti-csrf
Update for /logout
2024-05-14 14:08:35 -04:00
Sam Atkins 4ef3e53de3 fix(Terminal): Accept input from Chrome on Android
Xterm.js produces two kinds of events: onKey and onData. On a desktop,
these are effectively the same, but on mobile, IME inputs produce data
but not key presses. By listening to onData instead of onKey, we get
that input.

With some experimentation, I also found that we don't need the code to
handle enter, home, end, or Ctrl-Shift-V. All of these function as
expected without that code, so we can remove it and simplify this
further. :^)
2024-05-14 16:10:30 +01:00
Sam Atkins 2656b47640 chore: Update xterm
From version 5.4.0 onwards, xterm scopes its package names as
`@xterm/foo` instead of just `xterm-foo`.

We currently have a copy of xterm.css which we use instead of directly
including the one from the `@xterm/xterm` package, so I've updated the
contents of that too.
2024-05-14 16:10:30 +01:00
Sam Atkins fafbc292ca Remove xterm dependency from Phoenix
This is used by Terminal, not Phoenix.
2024-05-14 16:10:30 +01:00
KernelDeimos 800aef1942 Implement anti-CSRF for logout 2024-05-13 20:40:27 -04:00
KernelDeimos da7f73baa6 Add AntiCSRFService 2024-05-13 19:08:51 -04:00
KernelDeimos afb9d866b5 fix: Fix phoenix app prefix and TokenService test 2024-05-13 18:17:39 -04:00
Eric Dubé 7dc5929cfd Merge pull request #385 from HeyPuter/eric/dry-middleware
Add password requirement to: disable 2FA, change email
2024-05-13 16:38:59 -04:00
KernelDeimos c2f1694107 Require password entry to disable 2FA 2024-05-13 16:00:07 -04:00
KernelDeimos 23215bd6f7 Move change_email/start to password-protected endpoint 2024-05-13 16:00:07 -04:00
KernelDeimos 1493cacb69 Add rate-limiting to new password change endpoint 2024-05-13 16:00:07 -04:00
KernelDeimos 9076fddc0d Add new password change endpoint 2024-05-13 16:00:07 -04:00
KernelDeimos a89c9d59cf Add UserProtectedEndpointsService 2024-05-13 16:00:07 -04:00
KernelDeimos 15dec21118 doc(backend): Document the boot sequence
Now that the boot sequence is better formalized it may be documented.
2024-05-13 16:00:07 -04:00
KernelDeimos d800b12569 refactor(backend): Trigger webserver events in webserver
We were triggering webserver events in Kernel. This change improves
adherence to separation-of-concerns and ensures event cascading is
working as expected. This also better formalizes the boot sequence.
2024-05-13 01:05:49 -04:00
Eric Dubé 89ac491120 Merge pull request #391 from AtkinsSJ/truncate-filename
refactor: Put truncate_filename() helper in its own file
2024-05-10 12:54:46 -04:00
Eric Dubé 981a0f08fe Merge pull request #390 from AtkinsSJ/task-manager-components
refactor: Convert Task Manager to Components
2024-05-10 12:54:30 -04:00
Sam Atkins e53bfe6b62 refactor: Put truncate_filename() helper in its own file
Every user previously set the max_length as window.TRUNCATE_LENGTH, so
I've moved that constant into the truncate_filename file and set it as
the default if max_length is not specified.
2024-05-10 17:46:09 +01:00
Sam Atkins 9bb4570126 Re-use existing Task Manager rows if possible instead of recreating them
Most of the time, we'll already have a TaskManagerRow for the given
process, so we can just update its properties.

Iterating the results from #iter_tasks means we also insert the rows in
the correct order, regardless of their previous order.
2024-05-10 17:41:13 +01:00
Sam Atkins 5b43358219 fix: Only run Component initialization functions once
If the Component gets removed from the DOM and then re-added, it already
has contents, and we don't need to create them again. It also has
already had on_ready called, so that doesn't need to happen again
either.

This fix stops Components duplicating their content elements and
listener callbacks whenever they're moved around the document.
2024-05-10 17:41:01 +01:00
Sam Atkins cf605c8a38 refactor: Convert Task Manager to use Components
This currently behaves the same as it did before: It still recreates the
table contents every half a second. It should also look identical,
though it's possible I missed some small differences.

The component structure is:

TaskManagerTable
- Table
  - TaskManagerRow
  - TaskManagerRow
  - TaskManagerRow
  - ...

TaskManagerRow is implemented so that we can later move to modifying
them in place as the process tree changes, instead of having to replace
them all.

Otherwise, most of the code is just moved around, and not changed much.
2024-05-10 17:41:01 +01:00
Sam Atkins e304f6fc3a Add ability to look up a process by its uuid 2024-05-10 17:38:00 +01:00
Sam Atkins 09cee986f2 Add a Table component, based on the TaskManager table
For now, this is quite basic. The main feature is the sticky header.
2024-05-10 17:38:00 +01:00
Eric Dubé 3992fe1a45 Merge pull request #384 from AtkinsSJ/progress-dialogs
refactor: Replace several existing progress dialogs with one configurable one
2024-05-10 12:25:32 -04:00
Eric Dubé 17e08cafce Merge pull request #380 from AtkinsSJ/eslint-ci
Run ESLint on CI
2024-05-10 12:24:31 -04:00
Sam Atkins 7243ed718f Merge pull request #388 from AtkinsSJ/no-docker-images-for-prs
ci: Stop producing Docker images for PRs
2024-05-10 09:39:31 +01:00
Sam Atkins 387cfd758f Merge pull request #387 from ghostxbh/patch-1
fix: Eliminates duplicate translation keys
2024-05-10 09:31:52 +01:00
Sam Atkins c75a0bd311 ci: Wrap Docker images name with quotes
Not sure if this is required, but my IDE was complaining about it.
2024-05-10 09:29:49 +01:00
Sam Atkins 18633dcd88 ci: Stop producing Docker images for PRs 2024-05-10 09:28:55 +01:00
ghostxbh 5800350b25 fix: Eliminates duplicate translation keys 2024-05-10 10:41:21 +08:00
KernelDeimos cd2daa1910 Require email verification for contact form 2024-05-09 19:40:34 -04:00
KernelDeimos 8b6bbe003d fix(security) Disable 2FA configure if 2FA is enabled 2024-05-09 18:04:58 -04:00
Sam Atkins edebbee9e7 feat: Display upload errors in UIWindowProgress dialog
The object returned from UIWindowProgress() now has a `show_error()`
method, taking a title and message. Calling it will replace the content
of the window with those messages.

I've made use of this for file uploads. The only other place we
currently have errors we could show is for zipping and downloading
files, but we do not always have a progress dialog in that case, so I'll
leave that for now.

I think ideally, we would always create a progress dialog, and it would
then support being invisible initially, but appearing after a delay.
Then we'd always have an object to call `show_error()` on, and it could
then immediately show the dialog. But I'll get to that another day. :^)
2024-05-09 19:00:55 +01:00
Sam Atkins f3269693de Stop dumping binary data to the console
This was freaking out and freezing the Puter server, and my entire
terminal app. XD
2024-05-09 18:28:39 +01:00
Sam Atkins c2c87bf0ba refactor: Replace UIWindowDownloadDirProg with UIWindowProgress 2024-05-09 18:28:39 +01:00
Sam Atkins e525747002 refactor: Replace UIWindowCopyProgress with UIWindowProgress 2024-05-09 18:28:39 +01:00
Sam Atkins 6d8c709de8 Delete unused UIWindowDownloadProgress.js 2024-05-09 18:28:39 +01:00
Sam Atkins f07c13a50c feat: Show "Deleting /foo" in progress window when deleting files
Previously we showed "Moving /foo" which was confusing.

Also, make use of i18n replacements instead of gluing strings together,
because other languages might put the words in a different order. For
now, I've modified all the translations so that the "Moving foo" text
will appear as it did before, but these will require someone who
actually knows the different languages to check and correct them.
2024-05-09 18:19:05 +01:00
Sam Atkins c12312cbd3 refactor: Replace UIWindowMoveProgress with UIWindowProgress 2024-05-09 18:18:27 +01:00
Sam Atkins cb6c098f95 refactor: Replace UIWindowProgressEmptyTrash with UIWindowProgress
I noticed during this that emptying the trash from inside the Trash
window uses a different code path without a progress dialog, so I've
added a TODO to merge that in. I tried just using it directly but the
behaviour is a bit different. (The Trash one makes all the items fade
out.)
2024-05-09 18:17:15 +01:00
Sam Atkins 09ca82e1d8 refactor: Replace UIWindowNewFolderProgress with UIWindowProgress
This previously had code for the cancel button, but that cancel button
didn't exist. I've left the previous on-cancel code commented out with
a TODO.
2024-05-09 15:51:45 +01:00
Sam Atkins 5b565a69d7 refactor: Replace UIWindowUploadProgress with UIWindowProgress 2024-05-09 15:51:45 +01:00
Sam Atkins 52ddfc8801 Introduce a general-purpose progress window
We have 7 of these, which all have very similar code. Let's deduplicate
them! :^)
2024-05-09 15:51:45 +01:00
Sam Atkins df3f7e9a6e Allow Button component to not have button-block class
This needs a better solution for configuring the button's CSS classes,
but this works for now.
2024-05-09 12:38:29 +01:00
Sam Atkins 05aaa5b667 chore: Remove dead code from 2FA development
No `.qr-code-checkbox input`s now exist. Also, `.code-confirm-btn` is
only used by CodeEntryView, which doesn't use this Button component.
2024-05-09 12:12:33 +01:00
KernelDeimos df24c663df Invalidate email confirmation on password change 2024-05-08 22:28:41 -04:00
KernelDeimos 45e7f162a2 Add password change notification 2024-05-08 16:01:20 -04:00
Sam Atkins fbda8c8286 Run ESLint on CI
Run the ESLint static analysis tool on any code that is submitted, to
find possible bugs such as undefined functions and variables. We may
want to adjust the ESLint settings over time, but this seems like a
good start.

This is merged into the previous check-translations.yml action, because
that's also a form of linting. Possibly that could be reimplemented as
an ESLint plugin.
2024-05-08 18:53:37 +01:00
Sam Atkins 8c70efa058 Suppress remaining eslint errors
These two seem like bugs but are unclear to me how to fix, so I've added
FIXMEs.

/puter/packages/backend/src/routers/kvstore/clearItems.js
  41:32  error  'DB_MODE_WRITE' is not defined  no-undef

/puter/packages/backend/src/routers/whoami.js
  104:35  error  'db' is not defined  no-undef
2024-05-08 18:53:36 +01:00
Eric Dubé 65b489883d Merge pull request #381 from AtkinsSJ/web-components
Convert UIWindowThemeDialog to components
2024-05-08 12:15:23 -04:00
Sam Atkins 1b2608d6ee refactor: Replace component definition boilerplate with a function
Also, we can ask the CustomElementRegistry if it has an entry with a
given name, instead of polluting the window object.
2024-05-08 14:46:58 +01:00
Sam Atkins 9267b50666 Convert UIWindowThemeDialog to components
This also fixes the "Reset Colors" button not adjusting the sliders.
2024-05-08 14:46:58 +01:00
Sam Atkins 2604dae83c Resolve eslint issues in new 2FA code
/puter/src/UI/Settings/UITabSecurity.js
  13:13  error  'user' is not defined        no-undef
  31:13  error  'user' is not defined        no-undef
  32:70  error  'user' is not defined        no-undef
  36:30  error  'user' is not defined        no-undef
  40:82  error  'user' is not defined        no-undef
  41:83  error  'user' is not defined        no-undef
  87:41  error  'api_origin' is not defined  no-undef

/puter/src/UI/UIWindow2FASetup.js
  39:33  error  'api_origin' is not defined  no-undef
  51:37  error  'api_origin' is not defined  no-undef
  69:37  error  'api_origin' is not defined  no-undef

/puter/src/UI/UIWindowLogin.js
  202:73  error  'api_origin' is not defined  no-undef
  271:73  error  'api_origin' is not defined  no-undef
2024-05-08 09:49:58 +01:00
Sam Atkins 6778aa4343 Resolve eslint issues in Russian translation
/puter/src/i18n/translations/ru.js
  180:34  error  Irregular whitespace not allowed    no-irregular-whitespace
  257:9   error  Duplicate key 'storage_puter_used'  no-dupe-keys
2024-05-08 09:44:31 +01:00
KernelDeimos 5890b7e7bf Disable password reset token when email or password is changed 2024-05-07 20:18:11 -04:00
KernelDeimos d58aa33d2b Remove taskbar items from localstorage 2024-05-07 20:01:05 -04:00
KernelDeimos f62617a8bf Remove auth_token from /down call 2024-05-07 14:29:09 -04:00
KernelDeimos d20249f29a Send email notifications when 2FA state changes 2024-05-06 21:13:00 -04:00
Eric Dubé 0e16a3f3b4 Merge pull request #370 from HeyPuter/eric/2fa
2FA
2024-05-06 19:33:50 -04:00
Nariman Jelveh 5409547bba Make the 2fa disable prompt a child of the Settings window 2024-05-06 16:16:57 -07:00
KernelDeimos db8e2c3bf2 Address next batch of UX issues 2024-05-06 19:09:28 -04:00
KernelDeimos 4c53ec6dd3 Address UX issues 2024-05-06 18:53:43 -04:00
KernelDeimos b2d678ca95 Cleanup dead code 2024-05-06 16:45:03 -04:00
KernelDeimos adbefb4622 Cleanup log messages 2024-05-06 16:44:23 -04:00
KernelDeimos 429b7033a4 Improve error handling for 2FA rate limit 2024-05-06 16:35:35 -04:00
KernelDeimos 7f3e2852c6 Add rate limits 2024-05-06 16:12:54 -04:00
KernelDeimos 57d9c246c0 Fix css in firefox 2024-05-06 15:47:09 -04:00
KernelDeimos 7fce223a6d Fix OTP test endpoint 2024-05-06 15:40:34 -04:00
KernelDeimos abbbf0d030 Add confirmation for disabling 2FA 2024-05-06 15:36:38 -04:00
KernelDeimos a628358c9f Fix OTP time window 2024-05-06 15:02:14 -04:00
KernelDeimos 918eb3bb67 Put otpauth back on 9.2.4 2024-05-06 02:10:22 -04:00
KernelDeimos ecae1997aa Maybe this?? 2024-05-06 01:58:55 -04:00
KernelDeimos e4c7caa8ea Worth a try 2024-05-06 01:54:02 -04:00
KernelDeimos 54d1f05851 Install otpauth in root package.json because that... matters? 2024-05-06 01:48:25 -04:00
KernelDeimos 1592bc44fc Fix spinner getting stuck 2024-05-06 01:30:32 -04:00
KernelDeimos 77fedee58a Remove artifact 2024-05-06 00:13:24 -04:00
KernelDeimos 63e72a22e0 Fix settings card update 2024-05-06 00:02:46 -04:00
KernelDeimos 00c8ece07e Finish recovery codes 2024-05-06 00:02:46 -04:00
KernelDeimos 60a561c84c Re-use CodeEntryView for login 2024-05-06 00:02:46 -04:00
KernelDeimos 5cbe256120 Add missing part of previous commit 2024-05-06 00:02:46 -04:00
KernelDeimos 4ad50b14d6 Fix the duplicate loading issue 2024-05-06 00:02:46 -04:00
KernelDeimos df88373519 Remove test window open 2024-05-06 00:02:46 -04:00
KernelDeimos 099699198c Tweak QR code sizes 2024-05-06 00:02:46 -04:00
Nariman Jelveh 75bd1bc4c8 Update UIWindow2FASetup.js 2024-05-06 00:02:46 -04:00
Nariman Jelveh 12c883b6fd Remove the confirmation prompt when closing the 2FA setup winow
When exiting a window there should be a confirmation if exiting that window will irreversibly destroy work. For example, when you're working on a document and if you exit unsaved changes will be lost.
This doesn't seem to be the case. What work will be irreversibly lost?
2024-05-06 00:02:46 -04:00
Nariman Jelveh 144d647540 Improve styling 2024-05-06 00:02:46 -04:00
Nariman Jelveh c8a6d109ce Add icon for Security tab and warning/success styling for 2fa card 2024-05-06 00:02:46 -04:00
KernelDeimos 5fa3c6511f Fix padding and enable code 2024-05-06 00:02:46 -04:00
KernelDeimos a2a8f9de74 Fix cache state 2024-05-06 00:02:46 -04:00
KernelDeimos d72d83d0f3 Add i18n entries for 2FA setup 2024-05-06 00:02:46 -04:00
KernelDeimos c91c0afa71 Complete the 2FA setup flow 2024-05-06 00:02:46 -04:00
KernelDeimos a95fcc96be Add text components and styling 2024-05-06 00:02:46 -04:00
KernelDeimos f9c5a688b1 Fix code entry focus on init 2024-05-06 00:02:46 -04:00
KernelDeimos e9b8c452b9 Temporarily disable real check for testing 2024-05-06 00:02:46 -04:00
KernelDeimos 3e380ba844 Add otp test endpoint and next wizard step 2024-05-06 00:02:46 -04:00
KernelDeimos 22234ad1c1 Add the wizardy behaviour 2024-05-06 00:02:46 -04:00
KernelDeimos 662fd13548 Add code entry to 2FA wizard 2024-05-06 00:02:46 -04:00
KernelDeimos a672b8a58c Add UIWindow2FASetup 2024-05-06 00:02:46 -04:00
KernelDeimos 6e0cdb8a6b Document 2FA wizard structure 2024-05-06 00:02:46 -04:00
KernelDeimos 0baa678c8b Add Flexer 2024-05-06 00:02:46 -04:00
KernelDeimos c99747d7f2 Make using web components easier 2024-05-06 00:02:46 -04:00
KernelDeimos 2681a78501 Use username as otp label 2024-05-06 00:02:46 -04:00
KernelDeimos 3bf7737790 Add recovery codes 2024-05-06 00:02:46 -04:00
KernelDeimos 455d3946d6 Add checkboxes and cancel action for 2FA setup 2024-05-06 00:02:46 -04:00
KernelDeimos 2dfecb5287 Add 2fa setting and complete login flow 2024-05-06 00:02:46 -04:00
KernelDeimos abc12bd407 Add otp input at login 2024-05-06 00:02:46 -04:00
KernelDeimos bbf352caa4 Add missing package-lock.json changes 2024-05-06 00:02:46 -04:00
KernelDeimos d7c5c37cf8 Implement backend for 2FA 2024-05-06 00:02:46 -04:00
KernelDeimos 038373cbbc Fix filename inconsistency that breaks Linux support 2024-05-06 00:02:33 -04:00
Nariman Jelveh 321520741d Merge pull request #372 from nyedidikeke/naming-convention-patch-1
refactor: nomenclature, typo fixes, IDE and documentation enhancement 🔨
2024-05-05 19:46:16 -07:00
Didi Keke 2c75c636af docs: environment variable configuration 🌱 2024-05-06 01:21:59 +00:00
Didi Keke 01b7e523d0 chore: comment and fine tune .gitignore settings 🔨 2024-05-06 01:18:40 +00:00
Didi Keke 05d4a28adc chore: format content 📝 2024-05-06 01:14:36 +00:00
Didi Keke b89142c45c chore: include .vscode/extensions.json ⚓
- For recommendation of extensions or otherwise.
2024-05-05 20:31:08 +00:00
Didi Keke f9359bfb73 chore: ignore nested folders 🐜 2024-05-05 20:23:05 +00:00
Didi Keke 4d30740198 fix: typographical errors 🐛 2024-05-05 08:34:50 +00:00
Didi Keke 2d6dfd9002 chore: add word spelling dictionary 👼 2024-05-05 08:15:30 +00:00
Didi Keke 3914a14a2a chore: update .gitignore settings for VS Code 🚀
- All files within the `.vscode/` directory are ignored except for `settings.json`, `tasks.json`, and `launch.json`.
2024-05-05 08:11:13 +00:00
Didi Keke 2949f71691 fix: typographical error 🐛 2024-05-05 07:54:11 +00:00
Didi Keke 551121524c refactor: name from SelfhostedModule to SelfHostedModule 🔨 2024-05-05 07:53:55 +00:00
Nariman Jelveh 038c5e9a6e Merge pull request #371 from mafendi/main
Added Russian translation
2024-05-04 17:22:12 -07:00
Efendi 467aabe5ee Update translations.js
Added ru
2024-05-05 00:09:52 +03:00
Efendi 4f73641f46 Add files via upload 2024-05-05 00:07:07 +03:00
Nariman Jelveh 48e97b5ec2 Update UITaskbarItem.js 2024-05-04 12:34:28 -07:00
KernelDeimos a86106c0c1 Fix save_account token 2024-05-04 14:19:09 -04:00
Nariman Jelveh c9f3693785 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-05-03 21:32:26 -07:00
Nariman Jelveh 5151863a94 disable context menu on settings sidebar 2024-05-03 21:32:23 -07:00
Nariman Jelveh 16a81cdc7f Merge pull request #369 from nyedidikeke/patch-1
fix: reliability issue 🐛
2024-05-03 21:10:21 -07:00
Nariman Jelveh ebb6cf2a91 clean up console messages and errors 2024-05-03 20:49:12 -07:00
Didi Keke 1d546d9ef7 fix: reliability issue 🐛 2024-05-04 03:23:28 +00:00
Nariman Jelveh 6bef35b406 Fix issue with passive event listeners via jQuery 2024-05-03 20:21:26 -07:00
Nariman Jelveh ecd9d5493f Fix issue with trash not opening from taskbar 2024-05-03 19:57:48 -07:00
Nariman Jelveh 33a6f4c49f quick fix 2024-05-03 16:56:27 -07:00
Nariman Jelveh 3c92cd3198 Update initgui.js 2024-05-03 12:04:38 -07:00
Eric Dubé 4d0e6b4772 Merge pull request #336 from AtkinsSJ/app-tab-completion
Phoenix: Add tab-completion for command names
2024-05-03 12:39:07 -04:00
Eric Dubé ebdf0d9148 Merge pull request #348 from AtkinsSJ/eslint
Set up eslint, and try to resolve the issues it finds
2024-05-03 12:28:21 -04:00
Sam Atkins 44aa4f1b0a chore: Remove debugger calls
/puter/packages/phoenix/src/ansi-shell/arg-parsers/simple-parser.js
  30:38  warning  Unexpected 'debugger' statement  no-debugger

/puter/packages/phoenix/src/ansi-shell/pipeline/Coupler.js
  71:32  warning  Unexpected 'debugger' statement  no-debugger
2024-05-02 17:41:14 +01:00
Sam Atkins fa7c6bee96 fix: Correct variables used in errors in sign.js
I couldn't figure out how to get a name for the no_suitable_app error
unfortunately, so that's just commented out.

/puter/packages/backend/src/routers/sign.js
   65:74  error  'subject' is not defined  no-undef
  114:59  error  'subject' is not defined  no-undef
2024-05-02 17:39:01 +01:00
Sam Atkins fa3b86fa7e chore: Amend empty blocks in upload.js
/puter/packages/puter-js/src/modules/FileSystem/operations/upload.js
   63:22  error  Empty block statement  no-empty
  173:22  error  Empty block statement  no-empty
2024-05-02 17:31:17 +01:00
Sam Atkins 52d5299374 fix: Use correct variable for version number
/puter/packages/backend/src/services/ComplainAboutVersionsService.js
  30:36  error  'current_version' is not defined  no-undef
2024-05-02 17:30:53 +01:00
Sam Atkins 23d959bf64 chore: Clarify usage of window fields in index.js
/puter/src/index.js
  58:15  error  'loadScript' is not defined  no-undef
  59:15  error  'loadScript' is not defined  no-undef
  65:13  error  'gui_env' is not defined     no-undef
  66:15  error  'loadScript' is not defined  no-undef
  68:15  error  'loadCSS' is not defined     no-undef
  69:15  error  'loadScript' is not defined  no-undef
  73:5   error  'initgui' is not defined     no-undef
2024-05-02 17:26:41 +01:00
Sam Atkins 5198081c2b chore: Fix eslint issues in initgui.js
Almost entirely clarifying use of window fields

/puter/src/initgui.js
    82:28   error  'api_origin' is not defined                                   no-undef
   118:34   error  'url_query_params' is not defined                             no-undef
   120:17   error  'app_query_params' is not defined                             no-undef
   136:8    error  'url_query_params' is not defined                             no-undef
   136:51   error  'url_query_params' is not defined                             no-undef
   136:105  error  'url_query_params' is not defined                             no-undef
   138:14   error  'url_query_params' is not defined                             no-undef
   138:57   error  'url_query_params' is not defined                             no-undef
   138:110  error  'url_query_params' is not defined                             no-undef
   154:8    error  'url_query_params' is not defined                             no-undef
   154:54   error  'url_query_params' is not defined                             no-undef
   154:110  error  'url_query_params' is not defined                             no-undef
   164:17   error  'openerOrigin' is not defined                                 no-undef
   171:30   error  'openerOrigin' is not defined                                 no-undef
   173:37   error  'is_auth' is not defined                                      no-undef
   184:23   error  'getUserAppToken' is not defined                              no-undef
   184:39   error  'openerOrigin' is not defined                                 no-undef
   186:41   error  'is_auth' is not defined                                      no-undef
   195:23   error  'getUserAppToken' is not defined                              no-undef
   195:39   error  'openerOrigin' is not defined                                 no-undef
   205:8    error  'url_query_params' is not defined                             no-undef
   206:32   error  'url_query_params' is not defined                             no-undef
   218:23   error  'url_query_params' is not defined                             no-undef
   219:22   error  'openerOrigin' is not defined                                 no-undef
   219:38   error  'url_query_params' is not defined                             no-undef
   220:26   error  'url_query_params' is not defined                             no-undef
   228:29   error  'embedded_in_popup' is not defined                            no-undef
   238:20   error  'url_query_params' is not defined                             no-undef
   239:21   error  'url_query_params' is not defined                             no-undef
   270:36   error  'openerOrigin' is not defined                                 no-undef
   271:30   error  'checkUserSiteRelationship' is not defined                    no-undef
   271:56   error  'openerOrigin' is not defined                                 no-undef
   274:44   error  'logged_in_users' is not defined                              no-undef
   274:76   error  'userAppToken' is not defined                                 no-undef
   274:92   error  'url_query_params' is not defined                             no-undef
   284:17   error  'userAppToken' is not defined                                 no-undef
   288:25   error  'is_auth' is not defined                                      no-undef
   302:13   error  'url_query_params' is not defined                             no-undef
   303:38   error  'url_query_params' is not defined                             no-undef
   309:17   error  'logout' is not defined                                       no-undef
   331:13   error  'update_auth_data' is not defined                             no-undef
   363:8    error  'is_auth' is not defined                                      no-undef
   388:13   error  'update_auth_data' is not defined                             no-undef
   394:23   error  'get_auto_arrange_data' is not defined                        no-undef
   395:31   error  'desktop_path' is not defined                                 no-undef
   403:30   error  'url_query_params' is not defined                             no-undef
   405:38   error  'getUserAppToken' is not defined                              no-undef
   405:62   error  'openerOrigin' is not defined                                 no-undef
   415:35   error  'user' is not defined                                         no-undef
   417:24   error  'openerOrigin' is not defined                                 no-undef
   430:24   error  'openerOrigin' is not defined                                 no-undef
   438:20   error  'openerOrigin' is not defined                                 no-undef
   439:37   error  'getAppUIDFromOrigin' is not defined                          no-undef
   439:57   error  'openerOrigin' is not defined                                 no-undef
   444:35   error  'url_query_params' is not defined                             no-undef
   508:46   error  'url_query_params' is not defined                             no-undef
   630:54   error  'busy_indicator_hide_delay' is not defined                    no-undef
   636:49   error  'busy_indicator_hide_delay' is not defined                    no-undef
   647:13   error  'update_sites_cache' is not defined                           no-undef
   656:9    error  'refresh_desktop_background' is not defined                   no-undef
   661:9    error  'is_auth' is not defined                                      no-undef
   661:23   error  'first_visit_ever' is not defined                             no-undef
   662:12   error  'logged_in_users' is not defined                              no-undef
   679:14   error  'is_auth' is not defined                                      no-undef
   679:27   error  'first_visit_ever' is not defined                             no-undef
   693:12   error  'url_query_params' is not defined                             no-undef
   696:47   error  'url_query_params' is not defined                             no-undef
   704:18   error  'gui_origin' is not defined                                   no-undef
   715:17   error  'update_auth_data' is not defined                             no-undef
   728:8    error  'feature_flags' is not defined                                no-undef
   746:19   error  'get_auto_arrange_data' is not defined                        no-undef
   747:27   error  'desktop_path' is not defined                                 no-undef
   755:26   error  'url_query_params' is not defined                             no-undef
   758:34   error  'getUserAppToken' is not defined                              no-undef
   758:58   error  'openerOrigin' is not defined                                 no-undef
   768:31   error  'user' is not defined                                         no-undef
   770:20   error  'openerOrigin' is not defined                                 no-undef
   783:20   error  'openerOrigin' is not defined                                 no-undef
   792:16   error  'openerOrigin' is not defined                                 no-undef
   793:33   error  'getAppUIDFromOrigin' is not defined                          no-undef
   793:53   error  'openerOrigin' is not defined                                 no-undef
   801:31   error  'url_query_params' is not defined                             no-undef
   864:42   error  'url_query_params' is not defined                             no-undef
   987:50   error  'busy_indicator_hide_delay' is not defined                    no-undef
   993:45   error  'busy_indicator_hide_delay' is not defined                    no-undef
  1021:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1057:13   error  'active_item_container' is not defined                        no-undef
  1061:17   error  'active_item_container' is not defined                        no-undef
  1065:21   error  'active_item_container' is not defined                        no-undef
  1071:9    error  'active_element' is not defined                               no-undef
  1179:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1185:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1198:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1211:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1222:25   error  'select_ctxmenu_item' is not defined                          no-undef
  1255:22   error  'active_item_container' is not defined                        no-undef
  1256:39   error  'active_item_container' is not defined                        no-undef
  1257:21   error  'active_element' is not defined                               no-undef
  1258:23   error  'active_item_container' is not defined                        no-undef
  1263:27   error  'active_item_container' is not defined                        no-undef
  1264:39   error  'active_item_container' is not defined                        no-undef
  1267:27   error  'active_item_container' is not defined                        no-undef
  1268:39   error  'active_element' is not defined                               no-undef
  1268:74   error  'active_element' is not defined                               no-undef
  1268:93   error  'active_element' is not defined                               no-undef
  1271:27   error  'active_item_container' is not defined                        no-undef
  1272:39   error  'active_item_container' is not defined                        no-undef
  1275:39   error  'active_element' is not defined                               no-undef
  1275:74   error  'active_element' is not defined                               no-undef
  1275:93   error  'active_element' is not defined                               no-undef
  1323:114  error  'active_item_container' is not defined                        no-undef
  1331:21   error  'active_element' is not defined                               no-undef
  1334:27   error  'active_item_container' is not defined                        no-undef
  1390:37   error  'active_element' is not defined                               no-undef
  1407:31   error  'delete_item' is not defined                                  no-undef
  1419:37   error  'active_element' is not defined                               no-undef
  1419:115  error  'trash_path' is not defined                                   no-undef
  1436:31   error  'delete_item' is not defined                                  no-undef
  1438:55   error  'trash_path' is not defined                                   no-undef
  1445:59   error  'trash_path' is not defined                                   no-undef
  1446:61   error  'trash_path' is not defined                                   no-undef
  1452:37   error  'active_element' is not defined                               no-undef
  1456:25   error  'move_items' is not defined                                   no-undef
  1456:53   error  'trash_path' is not defined                                   no-undef
  1467:16   error  'keypress_item_seach_term' is not defined                     no-undef
  1468:30   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1470:13   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1471:17   error  'keypress_item_seach_term' is not defined                     no-undef
  1474:13   error  'keypress_item_seach_term' is not defined                     no-undef
  1477:38   error  'active_item_container' is not defined                        no-undef
  1480:108  error  'keypress_item_seach_term' is not defined                     no-undef
  1485:30   error  'active_item_container' is not defined                        no-undef
  1487:78   error  'keypress_item_seach_term' is not defined                     no-undef
  1505:19   error  'active_item_container' is not defined                        no-undef
  1509:17   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1509:63   error  'active_element' is not defined                               no-undef
  1518:16   error  'keypress_item_seach_term' is not defined                     no-undef
  1519:30   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1521:13   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1522:17   error  'keypress_item_seach_term' is not defined                     no-undef
  1525:13   error  'keypress_item_seach_term' is not defined                     no-undef
  1531:97   error  'keypress_item_seach_term' is not defined                     no-undef
  1538:67   error  'keypress_item_seach_term' is not defined                     no-undef
  1581:39   error  'active_element' is not defined                               no-undef
  1583:39   error  'active_element' is not defined                               no-undef
  1590:17   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1600:36   error  'active_element' is not defined                               no-undef
  1602:36   error  'active_element' is not defined                               no-undef
  1615:15   error  'mouseover_window' is not defined                             no-undef
  1616:15   error  'mouseover_window' is not defined                             no-undef
  1616:55   error  'trash_path' is not defined                                   no-undef
  1621:38   error  'active_element' is not defined                               no-undef
  1623:38   error  'active_element' is not defined                               no-undef
  1628:21   error  'clipboard' is not defined                                    no-undef
  1629:21   error  'clipboard_op' is not defined                                 no-undef
  1632:58   error  'trash_path' is not defined                                   no-undef
  1636:25   error  'clipboard' is not defined                                    no-undef
  1648:38   error  'active_element' is not defined                               no-undef
  1650:38   error  'active_element' is not defined                               no-undef
  1655:21   error  'clipboard' is not defined                                    no-undef
  1656:21   error  'clipboard_op' is not defined                                 no-undef
  1658:25   error  'clipboard' is not defined                                    no-undef
  1668:107  error  'last_enter_pressed_to_rename_ts' is not defined              no-undef
  1682:21   error  'launch_app' is not defined                                   no-undef
  1705:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1713:21   error  'active_item_container' is not defined                        no-undef
  1714:37   error  'active_item_container' is not defined                        no-undef
  1717:25   error  'open_item' is not defined                                    no-undef
  1736:16   error  'clipboard' is not defined                                    no-undef
  1745:37   error  'trash_path' is not defined                                   no-undef
  1745:74   error  'trash_path' is not defined                                   no-undef
  1745:96   error  'clipboard_op' is not defined                                 no-undef
  1748:20   error  'clipboard_op' is not defined                                 no-undef
  1749:21   error  'copy_clipboard_items' is not defined                         no-undef
  1750:25   error  'clipboard_op' is not defined                                 no-undef
  1751:21   error  'move_clipboard_items' is not defined                         no-undef
  1760:13   error  'undo_last_action' is not defined                             no-undef
  1767:9    error  'mouseX' is not defined                                       no-undef
  1768:9    error  'mouseY' is not defined                                       no-undef
  1771:13   error  'mouseX' is not defined                                       no-undef
  1771:29   error  'mouseY' is not defined                                       no-undef
  1771:38   error  'toolbar_height' is not defined                               no-undef
  1771:63   error  'mouseX' is not defined                                       no-undef
  1771:78   error  'mouseY' is not defined                                       no-undef
  1772:13   error  'current_active_snap_zone' is not defined                     no-undef
  1774:17   error  'mouseX' is not defined                                       no-undef
  1774:32   error  'mouseY' is not defined                                       no-undef
  1774:49   error  'mouseY' is not defined                                       no-undef
  1774:58   error  'desktop_height' is not defined                               no-undef
  1775:13   error  'current_active_snap_zone' is not defined                     no-undef
  1777:17   error  'mouseX' is not defined                                       no-undef
  1777:32   error  'mouseY' is not defined                                       no-undef
  1777:41   error  'desktop_height' is not defined                               no-undef
  1778:13   error  'current_active_snap_zone' is not defined                     no-undef
  1780:17   error  'mouseX' is not defined                                       no-undef
  1780:26   error  'desktop_width' is not defined                                no-undef
  1780:48   error  'mouseY' is not defined                                       no-undef
  1780:65   error  'mouseY' is not defined                                       no-undef
  1780:74   error  'desktop_height' is not defined                               no-undef
  1781:13   error  'current_active_snap_zone' is not defined                     no-undef
  1783:18   error  'mouseX' is not defined                                       no-undef
  1783:27   error  'desktop_width' is not defined                                no-undef
  1783:50   error  'mouseY' is not defined                                       no-undef
  1783:59   error  'toolbar_height' is not defined                               no-undef
  1783:84   error  'mouseX' is not defined                                       no-undef
  1783:93   error  'desktop_width' is not defined                                no-undef
  1783:115  error  'mouseY' is not defined                                       no-undef
  1784:13   error  'current_active_snap_zone' is not defined                     no-undef
  1786:17   error  'mouseX' is not defined                                       no-undef
  1786:26   error  'desktop_width' is not defined                                no-undef
  1786:48   error  'mouseY' is not defined                                       no-undef
  1786:58   error  'desktop_height' is not defined                               no-undef
  1787:13   error  'current_active_snap_zone' is not defined                     no-undef
  1789:17   error  'mouseY' is not defined                                       no-undef
  1789:26   error  'toolbar_height' is not defined                               no-undef
  1789:49   error  'mouseX' is not defined                                       no-undef
  1789:66   error  'mouseX' is not defined                                       no-undef
  1789:75   error  'desktop_width' is not defined                                no-undef
  1790:13   error  'current_active_snap_zone' is not defined                     no-undef
  1793:13   error  'current_active_snap_zone' is not defined                     no-undef
  1802:21   error  'mouseX' is not defined                                       no-undef
  1802:41   error  'mouseX' is not defined                                       no-undef
  1802:75   error  'mouseY' is not defined                                       no-undef
  1802:95   error  'mouseY' is not defined                                       no-undef
  1819:21   error  'mouseX' is not defined                                       no-undef
  1819:41   error  'mouseX' is not defined                                       no-undef
  1819:75   error  'mouseY' is not defined                                       no-undef
  1819:95   error  'mouseY' is not defined                                       no-undef
  1840:12   error  'mouseover_window' is not defined                             no-undef
  1841:15   error  'mouseover_window' is not defined                             no-undef
  1876:17   error  'upload_items' is not defined                                 no-undef
  1934:21   error  'logout' is not defined                                       no-undef
  1936:17   error  'logout' is not defined                                       no-undef
  1946:22   error  'gui_origin' is not defined                                   no-undef
  1951:50   error  'auth_token' is not defined                                   no-undef
  1958:18   error  Empty block statement                                         no-empty
2024-05-02 17:23:20 +01:00
Sam Atkins b6c491171c chore: Fix eslint issues in helper/ files
/puter/src/helpers/determine_active_container_parent.js
  22:30  error  'active_element' is not defined         no-undef
  25:30  error  'active_element' is not defined         no-undef
  29:30  error  'active_element' is not defined         no-undef
  32:41  error  'active_element' is not defined         no-undef
  32:61  error  'active_element' is not defined         no-undef
  33:30  error  'active_element' is not defined         no-undef
  36:41  error  'active_item_container' is not defined  no-undef
  37:28  error  'active_item_container' is not defined  no-undef

/puter/src/helpers/download.js
  51:27  error  'api_origin' is not defined           no-undef
  52:59  error  'auth_token' is not defined           no-undef
  92:16  error  'operation_cancelled' is not defined  no-undef

/puter/src/helpers/new_context_menu_item.js
  38:21  error  'create_folder' is not defined  no-undef
  48:21  error  'create_file' is not defined    no-undef
  56:21  error  'create_file' is not defined    no-undef
  70:25  error  'create_file' is not defined    no-undef

/puter/src/helpers/refresh_item_container.js
   83:13  error  'update_window_layout' is not defined                no-undef
   86:13  error  'update_details_layout_sort_visuals' is not defined  no-undef
  124:35  error  'trash_path' is not defined                          no-undef
  162:29  error  Empty block statement                                no-empty
  166:51  error  'path' is not defined                                no-undef
  168:34  error  'trash_path' is not defined                          no-undef
  168:62  error  'appdata_path' is not defined                        no-undef
  171:38  error  'desktop_item_positions' is not defined              no-undef
  178:37  error  'item_icon' is not defined                           no-undef
  207:31  error  'trash_path' is not defined                          no-undef
  216:21  error  'sort_items' is not defined                          no-undef
  217:26  error  Empty block statement                                no-empty
  222:13  error  'sort_items' is not defined                          no-undef
  233:17  error  'update_explorer_footer_item_count' is not defined   no-undef

/puter/src/helpers/update_title_based_on_uploads.js
  21:41  error  'active_uploads' is not defined  no-undef
  22:59  error  'active_uploads' is not defined  no-undef
  23:51  error  'active_uploads' is not defined  no-undef
  27:51  error  'active_uploads' is not defined  no-undef
2024-05-02 17:02:53 +01:00
Sam Atkins eefc0d41e1 chore: Fix eslint issues in helpers.js
Most of these are window fields that wanted `window.` prepended, but a
couple of issues are code that was using undefined variables (`ht` and
`dir_uuid`) and some switch-cases that I believe are intentionally
falling through.

/puter/src/helpers.js
    39:55   error  'auth_token' is not defined                                                                                            no-undef
    47:14   error  'api_origin' is not defined                                                                                            no-undef
    55:40   error  'auth_token' is not defined                                                                                            no-undef
    59:17   error  'logout' is not defined                                                                                                no-undef
   199:14   error  'api_origin' is not defined                                                                                            no-undef
   208:40   error  'auth_token' is not defined                                                                                            no-undef
   212:17   error  'logout' is not defined                                                                                                no-undef
   224:14   error  'api_origin' is not defined                                                                                            no-undef
   234:40   error  'auth_token' is not defined                                                                                            no-undef
   238:17   error  'logout' is not defined                                                                                                no-undef
   316:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   323:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   330:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   337:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   367:47   error  Unnecessary escape character: \/                                                                                       no-useless-escape
   411:14   error  'isString' is not defined                                                                                              no-undef
   420:47   error  'config' is not defined                                                                                                no-undef
   519:21   error  'globToRegExp' is not defined                                                                                          no-undef
   651:14   error  Empty block statement                                                                                                  no-empty
   656:9    error  'update_auth_data' is not defined                                                                                      no-undef
   678:36   error  'api_origin' is not defined                                                                                            no-undef
   722:5    error  'update_user_preferences' is not defined                                                                               no-undef
   740:24   error  'uuidv4' is not defined                                                                                                no-undef
   746:9    error  'appCallbackFunctions' is not defined                                                                                  no-undef
   789:14   error  'api_origin' is not defined                                                                                            no-undef
   794:40   error  'auth_token' is not defined                                                                                            no-undef
   861:33   error  'trash_path' is not defined                                                                                            no-undef
   867:21   error  Empty block statement                                                                                                  no-empty
   889:70   error  'trash_path' is not defined                                                                                            no-undef
   891:59   error  'trash_path' is not defined                                                                                            no-undef
   894:49   error  'trash_path' is not defined                                                                                            no-undef
   907:29   error  'docs_path' is not defined                                                                                             no-undef
   909:35   error  'pictures_path' is not defined                                                                                         no-undef
   911:35   error  'home_path' is not defined                                                                                             no-undef
   913:35   error  'videos_path' is not defined                                                                                           no-undef
   915:35   error  'desktop_path' is not defined                                                                                          no-undef
  1037:5    error  'getItem' is not defined                                                                                               no-undef
  1041:17   error  'setItem' is not defined                                                                                               no-undef
  1070:54   error  Empty block statement                                                                                                  no-empty
  1089:51   error  'ht' is not defined                                                                                                    no-undef
  1091:20   error  'desktop_loading_fade_delay' is not defined                                                                            no-undef
  1150:27   error  'operation_id' is not defined                                                                                          no-undef
  1151:5    error  'operation_cancelled' is not defined                                                                                   no-undef
  1169:21   error  'activate_item_name_editor' is not defined                                                                             no-undef
  1172:21   error  'actions_history' is not defined                                                                                       no-undef
  1181:54   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1187:37   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1211:21   error  'activate_item_name_editor' is not defined                                                                             no-undef
  1214:21   error  'actions_history' is not defined                                                                                       no-undef
  1245:22   error  'operation_id' is not defined                                                                                          no-undef
  1246:5    error  'operation_cancelled' is not defined                                                                                   no-undef
  1249:5    error  'update_explorer_footer_selected_items_count' is not defined                                                           no-undef
  1263:24   error  'clipboard' is not defined                                                                                             no-undef
  1264:29   error  'clipboard' is not defined                                                                                             no-undef
  1273:20   error  'operation_cancelled' is not defined                                                                                   no-undef
  1302:38   error  'clipboard' is not defined                                                                                             no-undef
  1303:38   error  'clipboard' is not defined                                                                                             no-undef
  1327:9    error  'actions_history' is not defined                                                                                       no-undef
  1335:40   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1341:29   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1354:22   error  'operation_id' is not defined                                                                                          no-undef
  1377:20   error  'operation_cancelled' is not defined                                                                                   no-undef
  1432:9    error  'actions_history' is not defined                                                                                       no-undef
  1440:40   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1446:29   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1486:17   error  'update_explorer_footer_item_count' is not defined                                                                     no-undef
  1487:17   error  'update_explorer_footer_selected_items_count' is not defined                                                           no-undef
  1500:8    error  'clipboard' is not defined                                                                                             no-undef
  1501:24   error  'clipboard' is not defined                                                                                             no-undef
  1502:61   error  'clipboard' is not defined                                                                                             no-undef
  1505:13   error  'move_items' is not defined                                                                                            no-undef
  1508:5    error  'clipboard' is not defined                                                                                             no-undef
  1537:23   error  'api_origin' is not defined                                                                                            no-undef
  1537:84   error  'auth_token' is not defined                                                                                            no-undef
  1556:34   error  'uuidv4' is not defined                                                                                                no-undef
  1565:45   error  'get_apps' is not defined                                                                                              no-undef
  1572:13   error  This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain  no-dupe-else-if
  1639:21   error  'root_dirname' is not defined                                                                                          no-undef
  1684:37   error  'gui_origin' is not defined                                                                                            no-undef
  1711:60   error  'app_domain' is not defined                                                                                            no-undef
  1723:64   error  'auth_token' is not defined                                                                                            no-undef
  1737:49   error  'auth_token' is not defined                                                                                            no-undef
  1748:12   error  'api_origin' is not defined                                                                                            no-undef
  1749:64   error  'api_origin' is not defined                                                                                            no-undef
  1800:13   error  'launch_apps' is not defined                                                                                           no-undef
  1803:13   error  'launch_apps' is not defined                                                                                           no-undef
  1803:43   error  'launch_apps' is not defined                                                                                           no-undef
  1806:13   error  'launch_apps' is not defined                                                                                           no-undef
  1806:34   error  'launch_apps' is not defined                                                                                           no-undef
  1810:22   error  'api_origin' is not defined                                                                                            no-undef
  1819:48   error  'auth_token' is not defined                                                                                            no-undef
  1867:56   error  'trash_path' is not defined                                                                                            no-undef
  1873:34   error  'trash_path' is not defined                                                                                            no-undef
  1942:30   error  'busy_indicator_hide_delay' is not defined                                                                             no-undef
  1948:25   error  'busy_indicator_hide_delay' is not defined                                                                             no-undef
  1954:48   error  'user_preferences' is not defined                                                                                      no-undef
  1955:9    error  'launch_app' is not defined                                                                                            no-undef
  1956:19   error  'user_preferences' is not defined                                                                                      no-undef
  1967:9    error  'launch_app' is not defined                                                                                            no-undef
  1978:25   error  'item_icon' is not defined                                                                                             no-undef
  1992:9    error  'window_nav_history' is not defined                                                                                    no-undef
  1992:45   error  'window_nav_history' is not defined                                                                                    no-undef
  1992:88   error  'window_nav_history_current_position' is not defined                                                                   no-undef
  1993:9    error  'window_nav_history' is not defined                                                                                    no-undef
  1994:9    error  'window_nav_history_current_position' is not defined                                                                   no-undef
  1996:9    error  'update_window_path' is not defined                                                                                    no-undef
  2009:22   error  'api_origin' is not defined                                                                                            no-undef
  2017:48   error  'auth_token' is not defined                                                                                            no-undef
  2021:25   error  'logout' is not defined                                                                                                no-undef
  2025:20   error  Empty block statement                                                                                                  no-empty
  2029:70   error  'suggest_apps_for_fsentry' is not defined                                                                              no-undef
  2040:17   error  'unzipItem' is not defined                                                                                             no-undef
  2057:17   error  'trigger_download' is not defined                                                                                      no-undef
  2065:13   error  'launch_app' is not defined                                                                                            no-undef
  2087:22   error  'operation_id' is not defined                                                                                          no-undef
  2088:5    error  'operation_cancelled' is not defined                                                                                   no-undef
  2129:12   error  'operation_cancelled' is not defined                                                                                   no-undef
  2166:30   error  Empty block statement                                                                                                  no-empty
  2173:20   error  'operation_cancelled' is not defined                                                                                   no-undef
  2182:34   error  'trash_path' is not defined                                                                                            no-undef
  2196:55   error  'trash_path' is not defined                                                                                            no-undef
  2196:116  error  'trash_path' is not defined                                                                                            no-undef
  2197:57   error  'trash_path' is not defined                                                                                            no-undef
  2201:46   error  'trash_path' is not defined                                                                                            no-undef
  2215:47   error  'trash_path' is not defined                                                                                            no-undef
  2254:25   error  'update_explorer_footer_item_count' is not defined                                                                     no-undef
  2255:25   error  'update_explorer_footer_selected_items_count' is not defined                                                           no-undef
  2260:34   error  'trash_path' is not defined                                                                                            no-undef
  2270:25   error  'update_window_path' is not defined                                                                                    no-undef
  2274:34   error  'trash_path' is not defined                                                                                            no-undef
  2279:46   error  'dir_uuid' is not defined                                                                                              no-undef
  2302:33   error  'item_icon' is not defined                                                                                             no-undef
  2303:42   error  'trash_path' is not defined                                                                                            no-undef
  2309:47   error  'trash_path' is not defined                                                                                            no-undef
  2331:41   error  'item_icon' is not defined                                                                                             no-undef
  2343:21   error  'sort_items' is not defined                                                                                            no-undef
  2348:21   error  'sort_items' is not defined                                                                                            no-undef
  2391:47   error  'trash_path' is not defined                                                                                            no-undef
  2397:51   error  'trash_path' is not defined                                                                                            no-undef
  2398:53   error  'trash_path' is not defined                                                                                            no-undef
  2413:34   error  'trash_path' is not defined                                                                                            no-undef
  2414:9    error  'actions_history' is not defined                                                                                       no-undef
  2418:40   error  'trash_path' is not defined                                                                                            no-undef
  2419:9    error  'actions_history' is not defined                                                                                       no-undef
  2428:12   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2641:21   error  'upload_items' is not defined                                                                                          no-undef
  2659:21   error  'trash_path' is not defined                                                                                            no-undef
  2679:21   error  'show_save_account_notice_if_needed' is not defined                                                                    no-undef
  2683:17   error  'active_uploads' is not defined                                                                                        no-undef
  2695:17   error  'active_uploads' is not defined                                                                                        no-undef
  2714:17   error  'actions_history' is not defined                                                                                       no-undef
  2722:25   error  'show_save_account_notice_if_needed' is not defined                                                                    no-undef
  2723:33   error  'upload_progress_hide_delay' is not defined                                                                            no-undef
  2726:24   error  'active_uploads' is not defined                                                                                        no-undef
  2733:24   error  'active_uploads' is not defined                                                                                        no-undef
  2739:24   error  'active_uploads' is not defined                                                                                        no-undef
  2766:17   error  'uuidv4' is not defined                                                                                                no-undef
  2772:16   error  'trash_path' is not defined                                                                                            no-undef
  2782:47   error  'trash_path' is not defined                                                                                            no-undef
  2782:108  error  'trash_path' is not defined                                                                                            no-undef
  2783:37   error  'trash_path' is not defined                                                                                            no-undef
  2786:36   error  'trash_path' is not defined                                                                                            no-undef
  2788:13   error  'update_explorer_footer_item_count' is not defined                                                                     no-undef
  2788:71   error  'trash_path' is not defined                                                                                            no-undef
  2793:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2799:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2815:18   error  'api_origin' is not defined                                                                                            no-undef
  2818:42   error  'auth_token' is not defined                                                                                            no-undef
  2991:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2998:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  3066:24   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  3074:24   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  3086:17   error  'actions_history' is not defined                                                                                       no-undef
  3095:17   error  'suggest_apps_for_fsentry' is not defined                                                                              no-undef
  3104:95   error  'truncate_filename' is not defined                                                                                     no-undef
  3104:123  error  'TRUNCATE_LENGTH' is not defined                                                                                       no-undef
  3111:84   error  'item_icon' is not defined                                                                                             no-undef
  3150:23   error  'update_sites_cache' is not defined                                                                                    no-undef
  3153:27   error  'determine_website_url' is not defined                                                                                 no-undef
  3158:17   error  'update_window_path' is not defined                                                                                    no-undef
  3166:17   error  'sort_items' is not defined                                                                                            no-undef
  3171:34   error  'truncate_filename' is not defined                                                                                     no-undef
  3171:66   error  'TRUNCATE_LENGTH' is not defined                                                                                       no-undef
  3205:9    error  'actions_history' is not defined                                                                                       no-undef
  3206:29   error  'actions_history' is not defined                                                                                       no-undef
  3211:13   error  'undo_create_file_or_folder' is not defined                                                                            no-undef
  3214:13   error  'rename_file' is not defined                                                                                           no-undef
  3217:13   error  'undo_upload' is not defined                                                                                           no-undef
  3220:13   error  'undo_copy' is not defined                                                                                             no-undef
  3223:13   error  'undo_move' is not defined                                                                                             no-undef
  3226:13   error  'undo_delete' is not defined                                                                                           no-undef
  3249:26   error  'get_html_element_from_options' is not defined                                                                         no-undef
  3251:9    error  'move_items' is not defined                                                                                            no-undef
  3257:26   error  'get_html_element_from_options' is not defined                                                                         no-undef
  3259:9    error  'move_items' is not defined                                                                                            no-undef
  3265:21   error  'global_element_id' is not defined                                                                                     no-undef
  3282:23   error  'determine_website_url' is not defined                                                                                 no-undef
  3324:42   error  'byte_format' is not defined                                                                                           no-undef
  3381:116  error  'truncate_filename' is not defined                                                                                     no-undef
  3381:148  error  'TRUNCATE_LENGTH' is not defined                                                                                       no-undef
  3396:5    error  'is_auto_arrange_enabled' is not defined                                                                               no-undef
  3398:5    error  'desktop_item_positions' is not defined                                                                                no-undef
  3408:8    error  'reset_item_positions' is not defined                                                                                  no-undef
  3409:9    error  'delete_desktop_item_positions' is not defined                                                                         no-undef
  3415:26   error  'desktop_item_positions' is not defined                                                                                no-undef
  3426:44   error  'desktop_item_positions' is not defined                                                                                no-undef
  3430:5    error  'desktop_item_positions' is not defined                                                                                no-undef
  3438:28   error  'is_fullscreen' is not defined                                                                                         no-undef
  3462:14   error  'window_for_app_instance' is not defined                                                                               no-undef
  3469:31   error  'iframe_for_app_instance' is not defined                                                                               no-undef
  3483:23   error  'window_for_app_instance' is not defined                                                                               no-undef
  3514:42   error  Unnecessary escape character: \[                                                                                       no-useless-escape
  3514:59   error  Unnecessary escape character: \/                                                                                       no-useless-escape
2024-05-02 16:54:17 +01:00
Sam Atkins e5cd2bed87 chore: Clarify usage of window fields in globals.js
/puter/src/globals.js
  124:65  error  'first_visit_animation' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 766da39138 chore: Clarify usage of window fields in UIWindowSignup.js
/puter/src/UI/UIWindowSignup.js
  154:22  error  'is_email' is not defined                 no-undef
  170:35  error  'check_password_strength' is not defined  no-undef
  188:22  error  'gui_origin' is not defined               no-undef
  203:21  error  'update_auth_data' is not defined         no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 72c0e118c3 chore: Clarify usage of window fields in UIWindowSessionList.js
/puter/src/UI/UIWindowSessionList.js
   33:117  error  'icons' is not defined             no-undef
   34:41   error  'logged_in_users' is not defined   no-undef
   35:32   error  'logged_in_users' is not defined   no-undef
  134:36   error  'logged_in_users' is not defined   no-undef
  141:17   error  'update_auth_data' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 66cdf98190 chore: Clarify usage of window fields in UIWindowSaveAccount.js
/puter/src/UI/UIWindowSaveAccount.js
  130:22  error  'api_origin' is not defined        no-undef
  142:48  error  'auth_token' is not defined        no-undef
  145:21  error  'update_auth_data' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins e5d4be6250 chore: Clarify usage of window fields in UIWindowRefer.js
/puter/src/UI/UIWindowRefer.js
  25:20  error  'gui_origin' is not defined  no-undef
  25:37  error  'user' is not defined        no-undef
  73:30  error  'socialLink' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 130b57b986 chore: Clarify usage of window fields in UIWindowRecoverPassword.js
/puter/src/UI/UIWindowRecoverPassword.js
   84:16  error  'is_email' is not defined    no-undef
   91:22  error  'api_origin' is not defined  no-undef
  101:25  error  'logout' is not defined      no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 2f30ae7a82 fix: Make url variable accessible to all users of it
Line 107 tries to use `url` but can't see it.

Also, clarify usage of window fields.

/puter/src/UI/UIWindowPublishWebsite.js
   67:67  error  'generate_identifier' is not defined  no-undef
  107:54  error  'url' is not defined                  no-undef
  110:17  error  'update_sites_cache' is not defined   no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins e983e9e9b7 chore: Clarify usage of window fields in UIWindowNewPassword.js
/puter/src/UI/UIWindowNewPassword.js
   48:38  error  'api_origin' is not defined               no-undef
  153:35  error  'check_password_strength' is not defined  no-undef
  163:22  error  'api_origin' is not defined               no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins b042f3c738 chore: Clarify usage of window fields in UIWindowMyWebsites.js
/puter/src/UI/UIWindowMyWebsites.js
  156:30  error  'api_origin' is not defined  no-undef
  164:56  error  'auth_token' is not defined  no-undef
  168:33  error  'logout' is not defined      no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ece37b62f2 chore: Clarify usage of window fields in progress dialogs
/puter/src/UI/UIWindowMoveProgress.js
  74:9  error  'operation_cancelled' is not defined  no-undef

/puter/src/UI/UIWindowNewFolderProgress.js
  67:9  error  'operation_cancelled' is not defined  no-undef

/puter/src/UI/UIWindowProgressEmptyTrash.js
  67:9  error  'operation_cancelled' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins abc70f2e92 chore: Clarify usage of window fields in UIWindowManageSessions.js
/puter/src/UI/UIWindowManageSessions.js
   91:41  error  'api_origin' is not defined  no-undef
  122:37  error  'api_origin' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 2ed258cb69 chore: Clarify usage of window fields in UIWindowLogin.js
/puter/src/UI/UIWindowLogin.js
  141:16  error  'is_email' is not defined          no-undef
  160:22  error  'gui_origin' is not defined        no-undef
  167:21  error  'update_auth_data' is not defined  no-undef
  180:59  error  'gui_origin' is not defined        no-undef
  186:29  error  'app_domain' is not defined        no-undef
  188:54  error  'gui_origin' is not defined        no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 6903ce0043 chore: Clarify usage of window fields in UIWindowItemProperties.js
/puter/src/UI/UIWindowItemProperties.js
  135:26   error  Empty block statement              no-empty
  147:120  error  'byte_format' is not defined       no-undef
  155:395  error  'extractSubdomain' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 0ebcbe516c chore: Clarify usage of window fields in UIWindowFontPicker.js
/puter/src/UI/UIWindowFontPicker.js
  45:12  error  'isString' is not defined             no-undef
  95:21  error  'scrollParentToChild' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins c44e0ca737 chore: Clarify usage of window fields in UIWindowFeedback.js
/puter/src/UI/UIWindowFeedback.js
  79:22  error  'api_origin' is not defined  no-undef
  84:48  error  'auth_token' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 7f050dc61a chore: Clarify usage of window fields in UIWindowDownloadProgress.js
/puter/src/UI/UIWindowDownloadProgress.js
  74:9  error  'operation_cancelled' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 93e13cdb06 chore: Clarify usage of window fields in UIWindowDesktopBGSettings.js
/puter/src/UI/UIWindowDesktopBGSettings.js
  168:26  error  'api_origin' is not defined  no-undef
  178:52  error  'auth_token' is not defined  no-undef
  182:29  error  'logout' is not defined      no-undef
  188:24  error  Empty block statement        no-empty
2024-05-02 11:21:50 +01:00
Sam Atkins dea3bc1a7f chore: Clarify use of window fields in UIWindowEmailConfirmationRequired
/puter/src/UI/UIWindowEmailConfirmationRequired.js
  113:26  error  'api_origin' is not defined         no-undef
  121:52  error  'auth_token' is not defined         no-undef
  125:29  error  'logout' is not defined             no-undef
  131:29  error  'refresh_user_data' is not defined  no-undef
  160:22  error  'api_origin' is not defined         no-undef
  165:48  error  'auth_token' is not defined         no-undef
  169:25  error  'logout' is not defined             no-undef
  188:13  error  'logout' is not defined             no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 2f6fcdb878 chore: Clarify usage of window fields in UIWindowDownloadProgress.js
/puter/src/UI/UIWindowDownloadProgress.js
  74:9  error  'operation_cancelled' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 3de32c2acc chore: Clarify usage of window fields in UIWindowColorPicker.js
/puter/src/UI/UIWindowColorPicker.js
  26:12  error  'isString' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ff28d2919b chore: Clarify usage of window fields in UIWindowChangeUsername.js
/puter/src/UI/UIWindowChangeUsername.js
   97:18  error  'api_origin' is not defined  no-undef
  101:44  error  'auth_token' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins e3fb25cf45 chore: Clarify usage of window fields in UIWindowChangePassword.js
/puter/src/UI/UIWindowChangePassword.js
  107:31  error  'check_password_strength' is not defined  no-undef
  117:18  error  'api_origin' is not defined               no-undef
  121:44  error  'auth_token' is not defined               no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins d39fd8659e chore: Clarify usage of window fields in UIWindow.js
And also add some missing imports.

/puter/src/UI/UIWindow.js
    33:20   error  'global_element_id' is not defined                            no-undef
    34:5    error  'last_window_zindex' is not defined                           no-undef
    48:5    error  'window_stack' is not defined                                 no-undef
    69:52   error  'uuidv4' is not defined                                       no-undef
    90:9    error  'is_embedded' is not defined                                  no-undef
   174:52   error  'last_window_zindex' is not defined                           no-undef
   174:94   error  'last_window_zindex' is not defined                           no-undef
   244:77   error  'is_embedded' is not defined                                  no-undef
   289:57   error  'navbar_path' is not defined                                  no-undef
   436:25   error  'launch_app' is not defined                                   no-undef
   456:9    error  'window_nav_history' is not defined                           no-undef
   457:9    error  'window_nav_history_current_position' is not defined          no-undef
   524:9    error  'animate_window_opening' is not defined                       no-undef
   599:17   error  'validate_fsentry_name' is not defined                        no-undef
   790:9    error  'navbar_path_droppable' is not defined                        no-undef
   791:9    error  'sidebar_item_droppable' is not defined                       no-undef
   801:33   error  'window_nav_history' is not defined                           no-undef
   801:63   error  'window_nav_history_current_position' is not defined          no-undef
   804:46   error  'root_dirname' is not defined                                 no-undef
   812:17   error  'window_nav_history_current_position' is not defined          no-undef
   812:68   error  'window_nav_history_current_position' is not defined          no-undef
   813:34   error  'window_nav_history' is not defined                           no-undef
   813:64   error  'window_nav_history_current_position' is not defined          no-undef
   815:17   error  'update_window_path' is not defined                           no-undef
   825:29   error  'window_nav_history_current_position' is not defined          no-undef
   826:38   error  'window_nav_history' is not defined                           no-undef
   834:25   error  'window_nav_history_current_position' is not defined          no-undef
   835:42   error  'window_nav_history' is not defined                           no-undef
   835:72   error  'window_nav_history_current_position' is not defined          no-undef
   840:59   error  'root_dirname' is not defined                                 no-undef
   847:29   error  'update_window_path' is not defined                           no-undef
   869:33   error  'window_nav_history' is not defined                           no-undef
   869:63   error  'window_nav_history_current_position' is not defined          no-undef
   872:46   error  'root_dirname' is not defined                                 no-undef
   880:17   error  'window_nav_history_current_position' is not defined          no-undef
   882:37   error  'window_nav_history' is not defined                           no-undef
   882:67   error  'window_nav_history_current_position' is not defined          no-undef
   885:21   error  'update_window_path' is not defined                           no-undef
   896:29   error  'window_nav_history_current_position' is not defined          no-undef
   896:86   error  'window_nav_history' is not defined                           no-undef
   897:38   error  'window_nav_history' is not defined                           no-undef
   905:25   error  'window_nav_history_current_position' is not defined          no-undef
   906:42   error  'window_nav_history' is not defined                           no-undef
   906:72   error  'window_nav_history_current_position' is not defined          no-undef
   911:59   error  'root_dirname' is not defined                                 no-undef
   918:29   error  'update_window_path' is not defined                           no-undef
   941:50   error  'root_dirname' is not defined                                 no-undef
   950:17   error  'window_nav_history' is not defined                           no-undef
   950:46   error  'window_nav_history' is not defined                           no-undef
   950:82   error  'window_nav_history_current_position' is not defined          no-undef
   951:17   error  'window_nav_history' is not defined                           no-undef
   952:17   error  'window_nav_history_current_position' is not defined          no-undef
   954:17   error  'update_window_path' is not defined                           no-undef
   968:25   error  'update_window_layout' is not defined                         no-undef
   983:25   error  'update_window_layout' is not defined                         no-undef
   986:25   error  'update_window_layout' is not defined                         no-undef
   997:13   error  'is_auth' is not defined                                      no-undef
  1023:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1106:21   error  'active_element' is not defined                               no-undef
  1117:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1143:18   error  'mouseover_window' is not defined                             no-undef
  1205:82   error  'mouseX' is not defined                                       no-undef
  1205:107  error  'mouseY' is not defined                                       no-undef
  1219:83   error  'mouseover_window' is not defined                             no-undef
  1244:31   error  'mouseover_window' is not defined                             no-undef
  1246:17   error  'copy_items' is not defined                                   no-undef
  1246:45   error  'mouseover_window' is not defined                             no-undef
  1252:21   error  'create_shortcut' is not defined                              no-undef
  1255:27   error  'mouseover_window' is not defined                             no-undef
  1264:17   error  'move_items' is not defined                                   no-undef
  1264:45   error  'mouseover_window' is not defined                             no-undef
  1286:13   error  'scale_window' is not defined                                 no-undef
  1302:13   error  'scale_window' is not defined                                 no-undef
  1359:21   error  'upload_items' is not defined                                 no-undef
  1413:47   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1414:49   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1420:53   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1435:17   error  'last_window_zindex' is not defined                           no-undef
  1460:29   error  'current_active_snap_zone' is not defined                     no-undef
  1469:50   error  'current_active_snap_zone' is not defined                     no-undef
  1473:43   error  'desktop_height' is not defined                               no-undef
  1474:40   error  'toolbar_height' is not defined                               no-undef
  1476:44   error  'last_window_zindex' is not defined                           no-undef
  1480:55   error  'current_active_snap_zone' is not defined                     no-undef
  1484:43   error  'desktop_height' is not defined                               no-undef
  1485:40   error  'toolbar_height' is not defined                               no-undef
  1487:44   error  'last_window_zindex' is not defined                           no-undef
  1491:55   error  'current_active_snap_zone' is not defined                     no-undef
  1495:43   error  'desktop_height' is not defined                               no-undef
  1496:40   error  'toolbar_height' is not defined                               no-undef
  1497:41   error  'desktop_width' is not defined                                no-undef
  1498:44   error  'last_window_zindex' is not defined                           no-undef
  1502:55   error  'current_active_snap_zone' is not defined                     no-undef
  1506:43   error  'desktop_height' is not defined                               no-undef
  1507:40   error  'toolbar_height' is not defined                               no-undef
  1510:44   error  'last_window_zindex' is not defined                           no-undef
  1514:55   error  'current_active_snap_zone' is not defined                     no-undef
  1517:42   error  'desktop_width' is not defined                                no-undef
  1518:43   error  'desktop_height' is not defined                               no-undef
  1519:40   error  'toolbar_height' is not defined                               no-undef
  1521:44   error  'last_window_zindex' is not defined                           no-undef
  1525:55   error  'current_active_snap_zone' is not defined                     no-undef
  1528:40   error  'toolbar_height' is not defined                               no-undef
  1528:57   error  'desktop_height' is not defined                               no-undef
  1531:43   error  'desktop_height' is not defined                               no-undef
  1532:44   error  'last_window_zindex' is not defined                           no-undef
  1536:55   error  'current_active_snap_zone' is not defined                     no-undef
  1539:40   error  'toolbar_height' is not defined                               no-undef
  1539:57   error  'desktop_height' is not defined                               no-undef
  1540:41   error  'desktop_width' is not defined                                no-undef
  1542:43   error  'desktop_height' is not defined                               no-undef
  1543:44   error  'last_window_zindex' is not defined                           no-undef
  1559:52   error  'current_active_snap_zone' is not defined                     no-undef
  1590:28   error  'current_active_snap_zone' is not defined                     no-undef
  1592:40   error  'toolbar_height' is not defined                               no-undef
  1595:43   error  'desktop_height' is not defined                               no-undef
  1599:33   error  'current_active_snap_zone' is not defined                     no-undef
  1601:40   error  'toolbar_height' is not defined                               no-undef
  1604:43   error  'desktop_height' is not defined                               no-undef
  1608:33   error  'current_active_snap_zone' is not defined                     no-undef
  1610:40   error  'toolbar_height' is not defined                               no-undef
  1613:43   error  'desktop_height' is not defined                               no-undef
  1617:33   error  'current_active_snap_zone' is not defined                     no-undef
  1619:40   error  'toolbar_height' is not defined                               no-undef
  1619:57   error  'desktop_height' is not defined                               no-undef
  1622:43   error  'desktop_height' is not defined                               no-undef
  1626:33   error  'current_active_snap_zone' is not defined                     no-undef
  1628:40   error  'toolbar_height' is not defined                               no-undef
  1628:57   error  'desktop_height' is not defined                               no-undef
  1629:41   error  'desktop_width' is not defined                                no-undef
  1631:43   error  'desktop_height' is not defined                               no-undef
  1635:33   error  'current_active_snap_zone' is not defined                     no-undef
  1637:40   error  'toolbar_height' is not defined                               no-undef
  1640:43   error  'desktop_height' is not defined                               no-undef
  1644:33   error  'current_active_snap_zone' is not defined                     no-undef
  1645:29   error  'scale_window' is not defined                                 no-undef
  1656:51   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1657:53   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1663:57   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1674:71   error  'taskbar_height' is not defined                               no-undef
  1676:51   error  'taskbar_height' is not defined                               no-undef
  1703:35   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1718:36   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1719:49   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1725:42   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1733:50   error  'toolbar_height' is not defined                               no-undef
  1734:38   error  'toolbar_height' is not defined                               no-undef
  1736:32   error  'toolbar_height' is not defined                               no-undef
  1773:13   error  'setItem' is not defined                                      no-undef
  1820:21   error  'scale_window' is not defined                                 no-undef
  1867:51   error  'trash_path' is not defined                                   no-undef
  1881:41   error  'sort_items' is not defined                                   no-undef
  1882:41   error  'set_sort_by' is not defined                                  no-undef
  1889:41   error  'sort_items' is not defined                                   no-undef
  1890:41   error  'set_sort_by' is not defined                                  no-undef
  1897:41   error  'sort_items' is not defined                                   no-undef
  1898:41   error  'set_sort_by' is not defined                                  no-undef
  1905:41   error  'sort_items' is not defined                                   no-undef
  1906:41   error  'set_sort_by' is not defined                                  no-undef
  1918:41   error  'sort_items' is not defined                                   no-undef
  1919:41   error  'set_sort_by' is not defined                                  no-undef
  1927:41   error  'sort_items' is not defined                                   no-undef
  1928:41   error  'set_sort_by' is not defined                                  no-undef
  1973:40   error  'clipboard' is not defined                                    no-undef
  1975:36   error  'clipboard_op' is not defined                                 no-undef
  1976:37   error  'copy_clipboard_items' is not defined                         no-undef
  1977:41   error  'clipboard_op' is not defined                                 no-undef
  1978:37   error  'move_clipboard_items' is not defined                         no-undef
  1986:39   error  'actions_history' is not defined                              no-undef
  1988:33   error  'undo_last_action' is not defined                             no-undef
  1998:33   error  'init_upload_using_dialog' is not defined                     no-undef
  2014:48   error  'UIWindowSaveAccount' is not defined                          no-undef
  2023:85   error  'UIWindowEmailConfirmationRequired' is not defined            no-undef
  2036:33   error  'launch_app' is not defined                                   no-undef
  2059:44   error  'mouseX' is not defined                                       no-undef
  2063:43   error  'mouseY' is not defined                                       no-undef
  2102:68   error  'trash_path' is not defined                                   no-undef
  2103:37   error  'delete_item' is not defined                                  no-undef
  2110:67   error  'trash_path' is not defined                                   no-undef
  2110:128  error  'trash_path' is not defined                                   no-undef
  2146:21   error  'upload_items' is not defined                                 no-undef
  2163:13   error  'enter_fullpage_mode' is not defined                          no-undef
  2173:8    error  'active_element' is not defined                               no-undef
  2174:9    error  'active_element' is not defined                               no-undef
  2195:25   error  'item_icon' is not defined                                    no-undef
  2210:9    error  'window_nav_history' is not defined                           no-undef
  2210:45   error  'window_nav_history' is not defined                           no-undef
  2210:88   error  'window_nav_history_current_position' is not defined          no-undef
  2211:9    error  'window_nav_history' is not defined                           no-undef
  2212:9    error  'window_nav_history_current_position' is not defined          no-undef
  2214:9    error  'update_window_path' is not defined                           no-undef
  2257:37   error  'item_icon' is not defined                                    no-undef
  2364:9    error  'update_window_path' is not defined                           no-undef
  2380:38   error  'root_dirname' is not defined                                 no-undef
  2389:9    error  'window_nav_history' is not defined                           no-undef
  2389:45   error  'window_nav_history' is not defined                           no-undef
  2389:88   error  'window_nav_history_current_position' is not defined          no-undef
  2390:9    error  'window_nav_history' is not defined                           no-undef
  2391:9    error  'window_nav_history_current_position' is not defined          no-undef
  2391:62   error  'window_nav_history' is not defined                           no-undef
  2392:9    error  'update_window_path' is not defined                           no-undef
  2436:59   error  'root_dirname' is not defined                                 no-undef
  2453:19   error  'clipboard' is not defined                                    no-undef
  2455:16   error  'clipboard_op' is not defined                                 no-undef
  2456:17   error  'copy_clipboard_items' is not defined                         no-undef
  2457:21   error  'clipboard_op' is not defined                                 no-undef
  2458:17   error  'move_clipboard_items' is not defined                         no-undef
  2484:18   error  'mouseover_window' is not defined                             no-undef
  2503:21   error  'create_shortcut' is not defined                              no-undef
  2515:17   error  'move_items' is not defined                                   no-undef
  2525:18   error  'mouseover_window' is not defined                             no-undef
  2605:12   error  'window_nav_history' is not defined                           no-undef
  2605:42   error  'window_nav_history' is not defined                           no-undef
  2605:84   error  'window_nav_history_current_position' is not defined          no-undef
  2612:12   error  'window_nav_history_current_position' is not defined          no-undef
  2626:55   error  'navbar_path' is not defined                                  no-undef
  2687:17   error  'update_window_layout' is not defined                         no-undef
  2690:21   error  'update_details_layout_sort_visuals' is not defined           no-undef
  2698:13   error  'update_window_path' is not defined                           no-undef
  2707:54   error  'root_dirname' is not defined                                 no-undef
  2712:9    error  'navbar_path_droppable' is not defined                        no-undef
  2715:5    error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  2727:18   error  'mouseover_window' is not defined                             no-undef
  2746:21   error  'create_shortcut' is not defined                              no-undef
  2758:17   error  'move_items' is not defined                                   no-undef
  2768:18   error  'mouseover_window' is not defined                             no-undef
  2807:36   error  'sendWindowWillCloseMsg' is not defined                       no-undef
  2819:23   error  'window_stack' is not defined                                 no-undef
  2829:17   error  'remove_taskbar_item' is not defined                          no-undef
  2836:17   error  'exit_fullpage_mode' is not defined                           no-undef
  2853:31   error  'window_stack' is not defined                                 no-undef
  2854:73   error  'window_stack' is not defined                                 no-undef
  2854:86   error  'window_stack' is not defined                                 no-undef
  2857:47   error  'window_stack' is not defined                                 no-undef
  2857:60   error  'window_stack' is not defined                                 no-undef
  2916:22   error  'window_stack' is not defined                                 no-undef
  2924:13   error  'active_item_container' is not defined                        no-undef
  2949:20   error  'toolbar_height' is not defined                               no-undef
  3007:14   error  'api_origin' is not defined                                   no-undef
  3017:40   error  'auth_token' is not defined                                   no-undef
  3021:17   error  'logout' is not defined                                       no-undef
  3083:43   error  'last_window_zindex' is not defined                           no-undef
  3123:38   error  'last_window_zindex' is not defined                           no-undef
  3127:98   error  'last_window_zindex' is not defined                           no-undef
  3131:100  error  'last_window_zindex' is not defined                           no-undef
  3147:81   error  'mouseX' is not defined                                       no-undef
  3147:106  error  'mouseY' is not defined                                       no-undef
  3151:9    error  'active_item_container' is not defined                        no-undef
  3153:34   error  'active_item_container' is not defined                        no-undef
  3155:9    error  'window_stack' is not defined                                 no-undef
  3157:11   error  'active_item_container' is not defined                        no-undef
  3252:5    error  'sort_items' is not defined                                   no-undef
  3253:5    error  'set_sort_by' is not defined                                  no-undef
  3258:14   error  'api_origin' is not defined                                   no-undef
  3267:40   error  'auth_token' is not defined                                   no-undef
  3271:17   error  'logout' is not defined                                       no-undef
  3280:21   error  'update_details_layout_sort_visuals' is not defined           no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 126b00b35c chore: Clarify usage of window fields in UITaskbarItem.js
/puter/src/UI/UITaskbarItem.js
   31:24  error  'global_element_id' is not defined    no-undef
  124:21  error  'launch_app' is not defined           no-undef
  143:21  error  'empty_trash' is not defined          no-undef
  158:25  error  'remove_taskbar_item' is not defined  no-undef
  160:21  error  'update_taskbar' is not defined       no-undef
  174:21  error  'update_taskbar' is not defined       no-undef
  250:73  error  'mouseover_window' is not defined     no-undef
  254:33  error  'path' is not defined                 no-undef
  297:21  error  'launch_app' is not defined           no-undef
  328:89  error  'mouseover_window' is not defined     no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 94291c4968 chore: Clarify usage of window fields in UITaskbar.js
/puter/src/UI/UITaskbar.js
   24:5    error  'global_element_id' is not defined      no-undef
   31:14   error  'api_origin' is not defined             no-undef
   36:40   error  'auth_token' is not defined             no-undef
   44:33   error  'global_element_id' is not defined      no-undef
   77:17   error  'launch_apps' is not defined            no-undef
   77:33   error  'launch_apps' is not defined            no-undef
   77:55   error  'launch_apps' is not defined            no-undef
   79:17   error  'launch_apps' is not defined            no-undef
   80:26   error  'api_origin' is not defined             no-undef
   85:52   error  'auth_token' is not defined             no-undef
   99:16   error  'launch_apps' is not defined            no-undef
  105:88   error  'launch_apps' is not defined            no-undef
  106:38   error  'launch_apps' is not defined            no-undef
  119:16   error  'launch_apps' is not defined            no-undef
  121:107  error  'launch_apps' is not defined            no-undef
  125:45   error  'launch_apps' is not defined            no-undef
  126:38   error  'launch_apps' is not defined            no-undef
  179:17   error  'launch_app' is not defined             no-undef
  201:25   error  'launch_app' is not defined             no-undef
  215:39   error  'trash_path' is not defined             no-undef
  228:68   error  'trash_path' is not defined             no-undef
  230:17   error  'launch_app' is not defined             no-undef
  236:13   error  'move_items' is not defined             no-undef
  236:31   error  'trash_path' is not defined             no-undef
  240:5    error  'make_taskbar_sortable' is not defined  no-undef
  262:22   error  Empty block statement                   no-empty
  284:29   error  'launch_app' is not defined             no-undef
  297:17   error  'update_taskbar' is not defined         no-undef
  301:17   error  'update_taskbar' is not defined         no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins a5821815bf chore: Clarify usage of window fields in UIPrompt.js
/puter/src/UI/UIPrompt.js
  26:12  error  'isString' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins c5612beff9 chore: Clarify usage of window fields in UIPopover.js
/puter/src/UI/UIPopover.js
  28:5   error  'global_element_id' is not defined  no-undef
  33:30  error  'global_element_id' is not defined  no-undef
  40:59  error  'global_element_id' is not defined  no-undef
  76:59  error  'taskbar_height' is not defined     no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins eecaf759ea chore: Clarify usage of window fields in UINotification.js
The click handler also makes use of the `options` parameter from
UINotification(), which isn't available there, so I've commented that
out. This needs more work.

/puter/src/UI/UINotification.js
  21:5   error  'global_element_id' is not defined  no-undef
  26:39  error  'global_element_id' is not defined  no-undef
  34:73  error  'global_element_id' is not defined  no-undef
  47:14  error  'toolbar_height' is not defined     no-undef
  55:12  error  'options' is not defined            no-undef
  55:36  error  'options' is not defined            no-undef
  56:13  error  'options' is not defined            no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 620a1a1334 chore: Clarify usage of window fields in UIItem.js
/puter/src/UI/UIItem.js
    42:21   error  'global_element_id' is not defined                            no-undef
    62:23   error  'determine_website_url' is not defined                        no-undef
   100:58   error  'timeago' is not defined                                      no-undef
   104:42   error  'byte_format' is not defined                                  no-undef
   161:151  error  'truncate_filename' is not defined                            no-undef
   161:183  error  'TRUNCATE_LENGTH' is not defined                              no-undef
   171:5    error  'show_or_hide_empty_folder_message' is not defined            no-undef
   178:64   error  'trash_path' is not defined                                   no-undef
   186:9    error  'update_explorer_footer_item_count' is not defined            no-undef
   190:10   error  'is_auto_arrange_enabled' is not defined                      no-undef
   217:21   error  'upload_items' is not defined                                 no-undef
   336:16   error  'mouseover_window' is not defined                             no-undef
   337:39   error  'mouseover_window' is not defined                             no-undef
   338:23   error  'mouseover_window' is not defined                             no-undef
   341:24   error  'mouseX' is not defined                                       no-undef
   341:46   error  'mouseX' is not defined                                       no-undef
   341:69   error  'mouseY' is not defined                                       no-undef
   341:90   error  'mouseY' is not defined                                       no-undef
   342:88   error  'mouseX' is not defined                                       no-undef
   342:113  error  'mouseY' is not defined                                       no-undef
   350:18   error  'is_auto_arrange_enabled' is not defined                      no-undef
   350:78   error  'trash_path' is not defined                                   no-undef
   352:17   error  'mouseover_window' is not defined                             no-undef
   358:17   error  'desktop_item_positions' is not defined                       no-undef
   359:17   error  'save_desktop_item_positions' is not defined                  no-undef
   383:73   error  'mouseover_window' is not defined                             no-undef
   427:21   error  'launch_app' is not defined                                   no-undef
   448:25   error  'copy_items' is not defined                                   no-undef
   450:25   error  'copy_items' is not defined                                   no-undef
   455:25   error  'create_shortcut' is not defined                              no-undef
   468:32   error  'desktop_item_positions' is not defined                       no-undef
   469:25   error  'save_desktop_item_positions' is not defined                  no-undef
   471:21   error  'move_items' is not defined                                   no-undef
   483:89   error  'mouseover_window' is not defined                             no-undef
   525:13   error  'open_item' is not defined                                    no-undef
   540:13   error  'open_item' is not defined                                    no-undef
   579:9    error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   596:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   651:34   error  'truncate_filename' is not defined                            no-undef
   651:66   error  'TRUNCATE_LENGTH' is not defined                              no-undef
   661:9    error  'rename_file' is not defined                                  no-undef
   678:13   error  'last_enter_pressed_to_rename_ts' is not defined              no-undef
   679:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   718:25   error  'activate_item_name_editor' is not defined                    no-undef
   763:78   error  'trash_path' is not defined                                   no-undef
   775:29   error  'move_items' is not defined                                   no-undef
   796:25   error  'zipItems' is not defined                                     no-undef
   810:25   error  'zipItems' is not defined                                     no-undef
   875:39   error  'delete_item' is not defined                                  no-undef
   877:63   error  'trash_path' is not defined                                   no-undef
   885:67   error  'trash_path' is not defined                                   no-undef
   885:116  error  'trash_path' is not defined                                   no-undef
   886:69   error  'trash_path' is not defined                                   no-undef
   906:29   error  'create_shortcut' is not defined                              no-undef
   925:25   error  'move_items' is not defined                                   no-undef
   925:53   error  'trash_path' is not defined                                   no-undef
   936:63   error  'trash_path' is not defined                                   no-undef
   936:122  error  'trash_path' is not defined                                   no-undef
   945:25   error  'open_item' is not defined                                    no-undef
   962:49   error  'suggest_apps_for_fsentry' is not defined                     no-undef
   984:37   error  'user_preferences' is not defined                             no-undef
   987:43   error  'user_preferences' is not defined                             no-undef
   989:42   error  'user_preferences' is not defined                             no-undef
  1007:41   error  'user_preferences' is not defined                             no-undef
  1008:72   error  'user_preferences' is not defined                             no-undef
  1011:33   error  'launch_app' is not defined                                   no-undef
  1047:29   error  'open_item' is not defined                                    no-undef
  1093:25   error  'launch_app' is not defined                                   no-undef
  1114:25   error  'empty_trash' is not defined                                  no-undef
  1127:29   error  'zipItems' is not defined                                     no-undef
  1129:29   error  'trigger_download' is not defined                             no-undef
  1140:25   error  'zipItems' is not defined                                     no-undef
  1151:41   error  'JSZip' is not defined                                        no-undef
  1180:25   error  'move_items' is not defined                                   no-undef
  1219:31   error  'clipboard' is not defined                                    no-undef
  1221:28   error  'clipboard_op' is not defined                                 no-undef
  1222:29   error  'copy_clipboard_items' is not defined                         no-undef
  1223:33   error  'clipboard_op' is not defined                                 no-undef
  1224:29   error  'move_clipboard_items' is not defined                         no-undef
  1247:25   error  'create_shortcut' is not defined                              no-undef
  1265:25   error  'move_items' is not defined                                   no-undef
  1265:47   error  'trash_path' is not defined                                   no-undef
  1290:35   error  'delete_item' is not defined                                  no-undef
  1292:63   error  'trash_path' is not defined                                   no-undef
  1299:67   error  'trash_path' is not defined                                   no-undef
  1299:128  error  'trash_path' is not defined                                   no-undef
  1300:57   error  'trash_path' is not defined                                   no-undef
  1313:25   error  'activate_item_name_editor' is not defined                    no-undef
  1373:9    error  'sort_items' is not defined                                   no-undef
  1376:9    error  'activate_item_name_editor' is not defined                    no-undef
  1433:31   error  'copy_to_clipboard' is not defined                            no-undef
  1517:9    error  'show_or_hide_empty_folder_message' is not defined            no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 9fc983f54a chore: Clarify usage of window fields in UIDesktop.js
/puter/src/UI/UIDesktop.js
    44:24   error  'gui_origin' is not defined                                   no-undef
    46:25   error  'auth_token' is not defined                                   no-undef
    86:5    error  'socket' is not defined                                       no-undef
    95:5    error  'socket' is not defined                                       no-undef
   104:5    error  'socket' is not defined                                       no-undef
   105:43   error  'trash_path' is not defined                                   no-undef
   106:45   error  'trash_path' is not defined                                   no-undef
   109:49   error  'trash_path' is not defined                                   no-undef
   112:5    error  'socket' is not defined                                       no-undef
   118:9    error  'launch_apps' is not defined                                  no-undef
   121:9    error  'launch_apps' is not defined                                  no-undef
   121:39   error  'launch_apps' is not defined                                  no-undef
   124:9    error  'launch_apps' is not defined                                  no-undef
   124:30   error  'launch_apps' is not defined                                  no-undef
   127:5    error  'socket' is not defined                                       no-undef
   146:5    error  'socket' is not defined                                       no-undef
   153:85   error  'truncate_filename' is not defined                            no-undef
   153:114  error  'TRUNCATE_LENGTH' is not defined                              no-undef
   156:77   error  'item_icon' is not defined                                    no-undef
   192:13   error  'update_window_path' is not defined                           no-undef
   199:13   error  'sort_items' is not defined                                   no-undef
   203:5    error  'socket' is not defined                                       no-undef
   206:9    error  'sendItemChangeEventToWatchingApps' is not defined            no-undef
   220:25   error  'fsentry.path' is assigned to itself                          no-self-assign
   233:17   error  'update_explorer_footer_item_count' is not defined            no-undef
   234:17   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   239:26   error  'trash_path' is not defined                                   no-undef
   249:17   error  'update_window_path' is not defined                           no-undef
   253:26   error  'trash_path' is not defined                                   no-undef
   280:25   error  'item_icon' is not defined                                    no-undef
   281:34   error  'trash_path' is not defined                                   no-undef
   287:39   error  'trash_path' is not defined                                   no-undef
   308:37   error  'item_icon' is not defined                                    no-undef
   319:17   error  'sort_items' is not defined                                   no-undef
   324:13   error  'sort_items' is not defined                                   no-undef
   328:5    error  'socket' is not defined                                       no-undef
   333:9    error  'refresh_user_data' is not defined                            no-undef
   336:5    error  'socket' is not defined                                       no-undef
   341:9    error  'refresh_user_data' is not defined                            no-undef
   344:5    error  'socket' is not defined                                       no-undef
   346:9    error  'sendItemChangeEventToWatchingApps' is not defined            no-undef
   360:85   error  'truncate_filename' is not defined                            no-undef
   360:114  error  'TRUNCATE_LENGTH' is not defined                              no-undef
   363:77   error  'item_icon' is not defined                                    no-undef
   398:13   error  'update_window_path' is not defined                           no-undef
   405:13   error  'sort_items' is not defined                                   no-undef
   409:5    error  'socket' is not defined                                       no-undef
   415:9    error  'sendItemChangeEventToWatchingApps' is not defined            no-undef
   440:81   error  'item_icon' is not defined                                    no-undef
   445:17   error  'sort_items' is not defined                                   no-undef
   455:29   error  'item_icon' is not defined                                    no-undef
   463:17   error  Duplicate key 'associated_app_name'                           no-dupe-keys
   470:17   error  'sort_items' is not defined                                   no-undef
   491:42   error  'desktop_path' is not defined                                 no-undef
   496:5    error  'getItem' is not defined                                      no-undef
   508:8    error  'url_query_params' is not defined                             no-undef
   525:9    error  'update_user_preferences' is not defined                      no-undef
   560:17   error  'upload_items' is not defined                                 no-undef
   560:52   error  'desktop_path' is not defined                                 no-undef
   577:16   error  'mouseover_window' is not defined                             no-undef
   585:69   error  'desktop_path' is not defined                                 no-undef
   613:17   error  'copy_items' is not defined                                   no-undef
   613:43   error  'desktop_path' is not defined                                 no-undef
   617:17   error  'move_items' is not defined                                   no-undef
   617:43   error  'desktop_path' is not defined                                 no-undef
   649:39   error  'is_auto_arrange_enabled' is not defined                      no-undef
   651:37   error  'is_auto_arrange_enabled' is not defined                      no-undef
   651:64   error  'is_auto_arrange_enabled' is not defined                      no-undef
   652:37   error  'store_auto_arrange_preference' is not defined                no-undef
   652:67   error  'is_auto_arrange_enabled' is not defined                      no-undef
   653:40   error  'is_auto_arrange_enabled' is not defined                      no-undef
   654:41   error  'sort_items' is not defined                                   no-undef
   655:41   error  'set_sort_by' is not defined                                  no-undef
   656:41   error  'clear_desktop_item_positions' is not defined                 no-undef
   658:41   error  'set_desktop_item_positions' is not defined                   no-undef
   668:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   671:37   error  'sort_items' is not defined                                   no-undef
   672:37   error  'set_sort_by' is not defined                                  no-undef
   677:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   680:37   error  'sort_items' is not defined                                   no-undef
   681:37   error  'set_sort_by' is not defined                                  no-undef
   686:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   689:37   error  'sort_items' is not defined                                   no-undef
   690:37   error  'set_sort_by' is not defined                                  no-undef
   695:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   698:37   error  'sort_items' is not defined                                   no-undef
   699:37   error  'set_sort_by' is not defined                                  no-undef
   708:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   712:37   error  'sort_items' is not defined                                   no-undef
   713:37   error  'set_sort_by' is not defined                                  no-undef
   718:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   722:37   error  'sort_items' is not defined                                   no-undef
   723:37   error  'set_sort_by' is not defined                                  no-undef
   757:43   error  'desktop_path' is not defined                                 no-undef
   767:35   error  'clipboard' is not defined                                    no-undef
   769:32   error  'clipboard_op' is not defined                                 no-undef
   770:33   error  'copy_clipboard_items' is not defined                         no-undef
   770:54   error  'desktop_path' is not defined                                 no-undef
   771:37   error  'clipboard_op' is not defined                                 no-undef
   772:33   error  'move_clipboard_items' is not defined                         no-undef
   780:35   error  'actions_history' is not defined                              no-undef
   782:29   error  'undo_last_action' is not defined                             no-undef
   791:29   error  'init_upload_using_dialog' is not defined                     no-undef
   818:9    error  'is_embedded' is not defined                                  no-undef
   911:12   error  'user' is not defined                                         no-undef
   922:13   error  'is_embedded' is not defined                                  no-undef
   940:8    error  'url_query_params' is not defined                             no-undef
   941:28   error  'url_query_params' is not defined                             no-undef
   943:35   error  'home_path' is not defined                                    no-undef
   944:16   error  'url_query_params' is not defined                             no-undef
   945:34   error  'url_query_params' is not defined                             no-undef
   950:29   error  'item_icon' is not defined                                    no-undef
   966:13   error  'launch_app' is not defined                                   no-undef
   967:23   error  'app_launched_from_url' is not defined                        no-undef
   970:25   error  'app_query_params' is not defined                             no-undef
  1017:40   error  'taskbar_height' is not defined                               no-undef
  1023:40   error  'user' is not defined                                         no-undef
  1024:9    error  'getItem' is not defined                                      no-undef
  1031:21   error  'setItem' is not defined                                      no-undef
  1125:47   error  'user' is not defined                                         no-undef
  1128:48   error  'user' is not defined                                         no-undef
  1131:25   error  'update_auth_data' is not defined                             no-undef
  1170:37   error  'listSupportedLanguages' is not defined                       no-undef
  1249:29   error  'logout' is not defined                                       no-undef
  1253:25   error  'logout' is not defined                                       no-undef
  1261:9    error  'is_fullscreen' is not defined                                no-undef
  1308:5    error  'launch_app' is not defined                                   no-undef
  1381:9    error  'launch_apps' is not defined                                  no-undef
  1460:14   error  'api_origin' is not defined                                   no-undef
  1468:40   error  'auth_token' is not defined                                   no-undef
  1488:14   error  'toolbar_height' is not defined                               no-undef
  1502:9    error  'reset_window_size_and_position' is not defined               no-undef
  1513:5    error  'refresh_desktop_background' is not defined                   no-undef
  1520:26   error  'window_border_radius' is not defined                         no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins dd7361441d chore: Clarify usage of window fields in UIContextMenu.js
/puter/src/UI/UIContextMenu.js
   23:21  error  'global_element_id' is not defined      no-undef
  117:57  error  'taskbar_height' is not defined         no-undef
  118:52  error  'taskbar_height' is not defined         no-undef
  260:17  error  'make_taskbar_sortable' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 63347843cb chore: Clarify usage of window fields in UIAlert.js
/puter/src/UI/UIAlert.js
  26:12  error  'isString' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins c2ef0a9578 chore: Clarify usage of window fields in Settings app
Solves these eslint issues:

/puter/src/UI/Settings/UITabAccount.js
  34:13   error  'user' is not defined  no-undef
  47:99   error  'user' is not defined  no-undef
  55:12   error  'user' is not defined  no-undef
  59:105  error  'user' is not defined  no-undef

/puter/src/UI/Settings/UITabLanguage.js
  35:37  error  'listSupportedLanguages' is not defined  no-undef

/puter/src/UI/Settings/UITabUsage.js
   45:18  error  'api_origin' is not defined   no-undef
   50:46  error  'auth_token' is not defined   no-undef
   54:21  error  'logout' is not defined       no-undef
   96:18  error  'api_origin' is not defined   no-undef
  101:46  error  'auth_token' is not defined   no-undef
  105:21  error  'logout' is not defined       no-undef
  116:51  error  'byte_format' is not defined  no-undef
  123:41  error  'byte_format' is not defined  no-undef
  124:45  error  'byte_format' is not defined  no-undef

/puter/src/UI/Settings/UIWindowChangeEmail.js
   96:18  error  'api_origin' is not defined  no-undef
  100:44  error  'auth_token' is not defined  no-undef

/puter/src/UI/Settings/UIWindowFinalizeUserDeletion.js
   29:12  error  'user' is not defined        no-undef
   97:16  error  'user' is not defined        no-undef
  115:22  error  'api_origin' is not defined  no-undef
  120:50  error  'auth_token' is not defined  no-undef
  127:25  error  'logout' is not defined      no-undef
  139:25  error  'logout' is not defined      no-undef

/puter/src/UI/Settings/UIWindowSettings.js
  48:162  error  'icons' is not defined  no-undef
  86:13   error  Duplicate key 'height'  no-dupe-keys
2024-05-02 11:21:50 +01:00
Sam Atkins d17e0b80b3 chore: Add missing import for node:console
Solves these eslint issues:

/puter/run-selfhosted.js
   49:9  error  'console' is not defined  no-undef
   64:5  error  'console' is not defined  no-undef
  127:5  error  'console' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 8d4a1e0ed3 fix: Add missing TextEncoder to PTT
Solves this eslint issue:

/puter/packages/terminal/src/pty/PTT.js
  35:29  error  'encoder' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 280479c0c6 chore: Clarify usage of window fields in IPC.js
Resolves these eslint errors:

/puter/src/IPC.js
    53:69  error  'appCallbackFunctions' is not defined                no-undef
    55:9   error  'appCallbackFunctions' is not defined                no-undef
    57:16  error  'appCallbackFunctions' is not defined                no-undef
    81:33  error  'window_for_app_instance' is not defined             no-undef
    84:27  error  'iframe_for_app_instance' is not defined             no-undef
   105:48  error  Empty block statement                                no-empty
   180:18  error  'api_origin' is not defined                          no-undef
   190:44  error  'auth_token' is not defined                          no-undef
   194:21  error  'logout' is not defined                              no-undef
   207:18  error  'api_origin' is not defined                          no-undef
   216:44  error  'auth_token' is not defined                          no-undef
   220:21  error  'logout' is not defined                              no-undef
   239:18  error  'api_origin' is not defined                          no-undef
   248:44  error  'auth_token' is not defined                          no-undef
   252:21  error  'logout' is not defined                              no-undef
   268:13  error  'is_auth' is not defined                             no-undef
   309:13  error  'is_auth' is not defined                             no-undef
   348:27  error  'window_for_app_instance' is not defined             no-undef
   360:27  error  'window_for_app_instance' is not defined             no-undef
   576:35  error  'uuidv4' is not defined                              no-undef
   582:9   error  'launch_app' is not defined                          no-undef
   597:37  error  'appdata_path' is not defined                        no-undef
   629:12  error  'appdata_signatures' is not defined                  no-undef
   633:23  error  'appdata_signatures' is not defined                  no-undef
   638:30  error  'appdata_path' is not defined                        no-undef
   647:25  error  'appdata_signatures' is not defined                  no-undef
   664:29  error  'appdata_signatures' is not defined                  no-undef
   682:13  error  'is_auth' is not defined                             no-undef
   717:13  error  'is_auth' is not defined                             no-undef
   745:13  error  'is_auth' is not defined                             no-undef
   773:13  error  'is_auth' is not defined                             no-undef
   783:22  error  'api_origin' is not defined                          no-undef
   793:48  error  'auth_token' is not defined                          no-undef
   797:25  error  'logout' is not defined                              no-undef
   825:13  error  'is_auth' is not defined                             no-undef
   857:36  error  'operation_id' is not defined                        no-undef
   872:41  error  'auth_token' is not defined                          no-undef
   873:41  error  'api_origin' is not defined                          no-undef
   939:45  error  'item_icon' is not defined                           no-undef
   951:33  error  'sort_items' is not defined                          no-undef
   954:29  error  'show_save_account_notice_if_needed' is not defined  no-undef
   998:38  error  'busy_indicator_hide_delay' is not defined           no-undef
  1004:33  error  'busy_indicator_hide_delay' is not defined           no-undef
  1018:37  error  'pictures_path' is not defined                       no-undef
  1020:37  error  'desktop_path' is not defined                        no-undef
  1022:37  error  'documents_path' is not defined                      no-undef
  1024:37  error  'videos_path' is not defined                         no-undef
  1026:37  error  'audio_path' is not defined                          no-undef
  1028:37  error  'appdata_path' is not defined                        no-undef
  1032:13  error  'is_auth' is not defined                             no-undef
  1044:28  error  'operation_id' is not defined                        no-undef
  1059:33  error  'auth_token' is not defined                          no-undef
  1060:33  error  'api_origin' is not defined                          no-undef
  1145:31  error  'iframe_for_app_instance' is not defined             no-undef
  1163:31  error  'window_for_app_instance' is not defined             no-undef
  1178:36  error  'get_apps' is not defined                            no-undef
  1199:11  error  'window_for_app_instance' is not defined             no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ca65ed1258 chore: Use this to refer to itemWatchCallbackFunctions field
Solves these eslint issues:

/puter/packages/puter-js/src/modules/UI.js
  418:20  error  'itemWatchCallbackFunctions' is not defined  no-undef
  418:74  error  'itemWatchCallbackFunctions' is not defined  no-undef
  419:21  error  'itemWatchCallbackFunctions' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 33785b3786 chore: Add missing imports for node:process 2024-05-02 11:21:50 +01:00
Sam Atkins 96e9c154bd chore: Fix a couple of regex related eslint issues
/puter/packages/phoenix/src/puter-shell/providers/ScriptCommandProvider.js
  27:38  error  Unnecessary escape character: \/  no-useless-escape

/puter/packages/phoenix/src/util/wrap-text.js
  24:33  error  Unexpected control character(s) in regular expression: \x1b  no-control-regex
2024-05-02 11:21:50 +01:00
Sam Atkins c8a20cadbf fix: Correct grep output when asking for line numbers
A couple of issues here:
- We didn't pass the line number to do_grep_line() so `i` was undefined
- Operator precedence messed with the ternary so when line numbers were
  requested, the line wouldn't be output.

Found thanks to this now-solved eslint issue:

/puter/packages/phoenix/src/puter-shell/coreutils/grep.js
  100:60  error  'i' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 71f8afab9a chore: Adjust comment for eslint
This was confusing its fallthrough detection:

/puter/packages/phoenix/src/puter-shell/coreutils/date.js
  132:21  error  Expected a 'break' statement before 'case'  no-fallthrough
2024-05-02 11:21:50 +01:00
Sam Atkins 6ad8f5e06a fix: Parse octal echo escapes
Found by this eslint issue:

/puter/packages/phoenix/src/puter-shell/coreutils/coreutil_lib/echo_escapes.js
  107:59  error  'hexchars' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 50d75cd2f9 refactor: Make loop condition non-constant
Resolves this eslint issue:

/puter/packages/phoenix/src/ansi-shell/readline/readline.js
  154:33  error  Unexpected constant condition  no-constant-condition
2024-05-02 11:21:50 +01:00
Sam Atkins 6d895dff42 chore: Remove empty block statement
Resolves this eslint issue:

/puter/packages/phoenix/src/ansi-shell/parsing/PuterShellParser.js
  25:9  error  Empty block statement  no-empty
2024-05-02 11:21:50 +01:00
Sam Atkins d4c2b492ef fix: Correct inverted instanceof check in SignalReader.read()
Also make tmp_value non-const because it gets modified later.

Solves these eslint issues:

/puter/packages/phoenix/src/ansi-shell/ioutil/SignalReader.js
  45:14  error  Unexpected negating the left operand of 'instanceof' operator  no-unsafe-negation
  46:13  error  'tmp_value' is constant                                        no-const-assign
2024-05-02 11:21:50 +01:00
Sam Atkins 64c886bfeb chore: Clarify setter to not return a value
Solves this eslint issue:

/puter/packages/phoenix/src/ansi-shell/ANSIShell.js
  86:23  error  Setter cannot return a value  no-setter-return
2024-05-02 11:21:50 +01:00
Sam Atkins 2094e05a2e chore: Comment out unreachable code in ExpectationService
The `return` looks temporary but I don't know this code well enough.

Solves this eslint issue:

/puter/packages/backend/src/services/runtime-analysis/ExpectationService.js
  94:9  error  Unreachable code  no-unreachable
2024-05-02 11:21:50 +01:00
Sam Atkins 0df0de6507 chore: Define def() and defv() using const
Fixes these eslint issues:

/puter/packages/backend/src/services/auth/TokenService.js
   3:1   error  'def' is not defined   no-undef
  18:1   error  'defv' is not defined  no-undef
  61:11  error  'def' is not defined   no-undef
  69:21  error  'defv' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 01ab6b88ea chore: Remove unused uses of uuid_user in save_account.js
The variable doesn't exist, and we never use it after this. Seems like a
copy-paste error.

Solves these eslint errors:

/puter/packages/backend/src/routers/save_account.js
  90:9   error  'uuid_user' is not defined  no-undef
  91:9   error  'uuid_user' is not defined  no-undef
  91:21  error  'uuid_user' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 9b3dd6b753 chore: Fix eslint issues in backend util
/puter/packages/backend/src/util/stdioutil.js
  26:24  error  Unexpected control character(s) in regular expression: \x1b  no-control-regex

/puter/packages/backend/src/util/streamutil.js
  368:1  error  'string_to_stream' is not defined  no-undef
  463:5  error  'string_to_stream' is not defined  no-undef

/puter/packages/backend/src/util/strutil.js
  42:1  error  'format_as_usd' is not defined  no-undef
  56:5  error  'format_as_usd' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 60523dc7a7 chore: Fix some eslint issues in services
/puter/packages/backend/src/services/ContextInitService.js
  57:18  error  'async_factory' is not defined  no-undef

/puter/packages/backend/src/services/StorageService.js
  22:5  error  Expected to call 'super()'  constructor-super

/puter/packages/backend/src/services/WebServerService.js
  258:35  error  'services' is not defined  no-undef

/puter/packages/backend/src/services/auth/AuthService.js
  52:13  error  Unreachable code  no-unreachable

/puter/packages/backend/src/services/drivers/implementations/BaseImplementation.js
   64:25  error  'services' is not defined  no-undef
   75:39  error  'services' is not defined  no-undef
  117:39  error  'services' is not defined  no-undef
  123:42  error  'services' is not defined  no-undef
  149:42  error  'services' is not defined  no-undef
  168:38  error  'services' is not defined  no-undef

/puter/packages/backend/src/services/drivers/implementations/PuterDriverProxy.js
  43:5  error  Expected to call 'super()'              constructor-super
  44:9  error  'this' is not allowed before 'super()'  no-this-before-super

/puter/packages/backend/src/services/drivers/meta/Construct.js
  125:9  error  Unreachable code  no-unreachable

/puter/packages/backend/src/services/runtime-analysis/PagerService.js
  49:41  error  'util' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ca3f9a823d chore: Fix some eslint issues in routers
/puter/packages/backend/src/routers/open_item.js
  48:10  error  Unexpected negating the left operand of 'instanceof' operator  no-unsafe-negation

/puter/packages/backend/src/routers/save_account.js
  106:34  error  'get_user' is not defined   no-undef

/puter/packages/backend/src/routers/sign.js
  37:10  error  Unexpected negating the left operand of 'instanceof' operator  no-unsafe-negation
2024-05-02 11:21:50 +01:00
Sam Atkins 0c0846eef9 chore: Fix some backend router eslint issues
/puter/packages/backend/src/routers/auth/list-permissions.js
  36:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/routers/auth/list-sessions.js
  17:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/routers/auth/revoke-user-app.js
  34:15  error  'APIError' is not defined  no-undef
  43:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/routers/delete-site.js
  43:11  error  Unexpected empty object pattern  no-empty-pattern

/puter/packages/backend/src/routers/drivers/usage.js
  146:11  error  'k' is not defined  no-undef
  147:21  error  'k' is not defined  no-undef
  147:52  error  'k' is not defined  no-undef

/puter/packages/backend/src/routers/drivers/xd.js
  68:5  error  'window' is not defined  no-undef
  69:21  error  Parsing error: The keyword 'interface' is reserved

/puter/packages/backend/src/routers/filesystem_api/batch/all.js
   51:21  error  'get_app' is not defined       no-undef
  224:13  error  Unexpected constant condition  no-constant-condition

/puter/packages/backend/src/routers/filesystem_api/copy.js
   70:10  error  Unexpected constant condition  no-constant-condition
  106:13  error  Duplicate key 'new_name'       no-dupe-keys

/puter/packages/backend/src/routers/filesystem_api/read.js
  80:5  error  Unreachable code  no-unreachable

/puter/packages/backend/src/routers/filesystem_api/token-read.js
   53:9  error  Unreachable code  no-unreachable
   58:9  error  Unreachable code  no-unreachable
  104:5  error  Unreachable code  no-unreachable

/puter/packages/backend/src/routers/hosting/puter-site.js
  65:21  error  Unexpected constant nullishness on the left-hand side of a `??` expression  no-constant-binary-expression
2024-05-02 11:21:50 +01:00
Sam Atkins b4af28a91b chore: Miscellaneous eslint fixes
/puter/packages/backend/src/om/entitystorage/ValidationES.js
  89:25  error  Do not assign to the exception parameter  no-ex-assign

/puter/packages/backend/src/om/proptypes/__all__.js
  166:17  warning  Unexpected 'debugger' statement  no-debugger

/puter/packages/backend/src/routers/_default.js
  405:31  error  'err' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 4879ee93bf chore: Fix eslint errors in backend/src/helpers.js
/puter/packages/backend/src/helpers.js
   682:9   error  'sharing_users' is not defined     no-undef
   689:12  error  'sharing_users' is not defined     no-undef
   690:28  error  'sharing_users' is not defined     no-undef
   695:28  error  'sharing_users' is not defined     no-undef
   720:9   error  'shared_fsentries' is not defined  no-undef
   733:12  error  'shared_fsentries' is not defined  no-undef
   734:28  error  'shared_fsentries' is not defined  no-undef
   735:17  error  'shared_fsentries' is not defined  no-undef
   735:58  error  'shared_fsentries' is not defined  no-undef
   736:31  error  'shared_fsentries' is not defined  no-undef
   900:57  error  'e' is not defined                 no-undef
  1849:18  error  Empty block statement              no-empty
2024-05-02 11:21:50 +01:00
Sam Atkins 8ab1cd0ca8 chore: Remove unused 'connective' source files 2024-05-02 11:21:50 +01:00
Sam Atkins 11f3e29604 chore: Disable eslint checks on puter-js tests
These currently work in a way that's different from what eslint expects,
so disable it. At some point it would be good if it could check them
(and if the tests could run on CI) but right now they just make a lot of
noise.
2024-05-02 11:21:50 +01:00
Sam Atkins 8cf6379de3 chore: Correct eslint errors in backend filesystem
Removes or disables the following eslint errors/warnings:

/puter/packages/backend/src/api/filesystem/FlagParam.js
  33:19  error  'APIError' is not defined  no-undef
  47:19  error  'APIError' is not defined  no-undef
  58:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/api/filesystem/StringParam.js
  32:19  error  'APIError' is not defined  no-undef
  39:13  error  'APIError' is not defined  no-undef
  46:19  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/filesystem/FilesystemService.js
  141:17  warning  Unexpected 'debugger' statement  no-debugger
  366:21  error    'services' is not defined        no-undef

/puter/packages/backend/src/filesystem/batch/BatchExecutor.js
  121:21  error  Do not assign to the exception parameter  no-ex-assign

/puter/packages/backend/src/filesystem/hl_operations/hl_data_read.js
  44:19  error  'APIError' is not defined     no-undef
  47:22  error  'chkperm' is not defined      no-undef
  48:19  error  'APIError' is not defined     no-undef
  51:29  error  'LLRead' is not defined       no-undef
  54:13  error  'version_id' is not defined   no-undef
  88:35  error  'PassThrough' is not defined  no-undef

/puter/packages/backend/src/filesystem/hl_operations/hl_mkdir.js
  68:49  error  'fs' is not defined  no-undef

/puter/packages/backend/src/filesystem/hl_operations/hl_move.js
  102:33  error  'get_user' is not defined  no-undef
  104:35  error  'get_user' is not defined  no-undef
  110:33  error  'df' is not defined        no-undef

/puter/packages/backend/src/filesystem/hl_operations/hl_read.js
  54:13  error  'stream' is constant  no-const-assign

/puter/packages/backend/src/filesystem/hl_operations/hl_stat.js
  40:37  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/filesystem/lib/PuterPath.js
  67:5  error  Expected to return a value in getter 'hasRelativePortion'  getter-return

/puter/packages/backend/src/filesystem/ll_operations/ll_copy_idea.js
   53:21  error  'UploadProgressTracker' is not defined   no-undef
   73:17  error  'PuterS3StorageStrategy' is not defined  no-undef
  137:22  error  'LLFilesystemOperation' is not defined   no-undef

/puter/packages/backend/src/filesystem/ll_operations/ll_read.js
  102:65  error  'offset' is not defined  no-undef
  102:73  error  'offset' is not defined  no-undef
  102:80  error  'length' is not defined  no-undef

/puter/packages/backend/src/filesystem/ll_operations/ll_rmnode.js
  43:23  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/filesystem/storage/SystemFSEntryService.js
  101:26  error  '_path' is not defined  no-undef

/puter/packages/backend/src/filesystem/validation.js
  27:29  error  Unexpected control character(s) in regular expression: \x00, \x1f  no-control-regex
  28:29  error  Unexpected control character(s) in regular expression: \x00, \x1f  no-control-regex
  28:31  error  Unnecessary escape character: \/                                   no-useless-escape
2024-05-02 11:21:50 +01:00
Sam Atkins 4a426ce045 chore: Remove duplicate translation keys 2024-05-02 11:21:50 +01:00
Sam Atkins 25b35769c5 chore: Set-up eslint
eslint is a static analysis tool that tries to identify bugs and
mistakes in the code. We have quite a variety of code in this repo so
the config is a little complicated, but I've tried to make it clear.
It's found a *lot* of issues (over 1700), and while many of which will
not be actual problems, (it doesn't like us using window properties
without `window.`,) but some definitely are.
2024-05-02 11:21:50 +01:00
Nariman Jelveh 4b0c474537 Merge pull request #363 from AtkinsSJ/document-selfhost-limitations
docs: Explain self-host differences
2024-05-01 11:09:37 -07:00
Sam Atkins a74b8e32fa docs: Explain self-host differences 2024-04-30 16:29:57 +01:00
Sam Atkins 251368e749 docs: Link to sections in README 2024-04-30 16:29:47 +01:00
Nariman Jelveh 0b1f963f0b Add fun HN badges! 2024-04-30 00:01:36 -07:00
Nariman Jelveh 4ea54823b0 Merge pull request #360 from Bashamega/bashamega-patch
Fixes the scroll bar
2024-04-29 22:20:33 -07:00
Bashamega c6ffa6e9e1 fix 2024-04-30 06:48:11 +03:00
KernelDeimos 8e6ee9ea79 Fix oversight in token compression 2024-04-29 22:48:10 -04:00
KernelDeimos e7e7363fa7 Drop useless header 2024-04-29 22:34:19 -04:00
KernelDeimos 5a76bad28d fix: reduce token lengths 2024-04-29 21:46:02 -04:00
KernelDeimos c1e4eeec32 Add TokenService and test utility 2024-04-29 21:11:31 -04:00
KernelDeimos d2de46edfb fix: increase QR code size 2024-04-29 19:48:01 -04:00
KernelDeimos 04432df554 feat: improve password recovery experience 2024-04-29 19:26:29 -04:00
KernelDeimos c44028f413 refactor: normalize email calls 2024-04-29 17:34:24 -04:00
Nariman Jelveh 8cad610a54 more sanitization, just in case 2024-04-29 14:09:54 -07:00
Nariman Jelveh f807a28e95 bugfix 2024-04-29 12:05:41 -07:00
KernelDeimos 4c1d5a4b6d fix: fix error handling for outdated node versions 2024-04-29 02:42:04 -04:00
Nariman Jelveh ecfbc44a20 safely escape settings strings 2024-04-28 16:02:54 -07:00
Nariman Jelveh 63c81d6fff Update UITabAccount.js 2024-04-27 19:29:44 -07:00
Nariman Jelveh 42d85abfc2 Update WebServerService.js 2024-04-27 19:10:10 -07:00
Nariman Jelveh fd4e2f59dc Update WebServerService.js 2024-04-27 19:03:48 -07:00
Nariman Jelveh 053728a03f Validate the Host header before responding to requests 2024-04-27 18:52:01 -07:00
Nariman Jelveh 92f6c8003b Merge pull request #352 from enweazudaniel/main
Language: Add Igbo translations
2024-04-27 14:49:28 -07:00
Nariman Jelveh 826afd7653 change en to ig for object name 2024-04-27 14:38:18 -07:00
enweazudaniel 0df9519f76 Language: Add Igbo 2024-04-27 12:06:29 +01:00
enweazudaniel d5d0f67797 Language: Add (Igbo) ig.js 2024-04-27 12:03:18 +01:00
Nariman Jelveh 219cc94fbf Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-26 19:13:34 -07:00
Nariman Jelveh bfa6419070 Update helpers.js 2024-04-26 19:13:22 -07:00
KernelDeimos d7d6ff0cca Rate limit updates 2024-04-26 21:02:01 -04:00
KernelDeimos 79d6f64451 Notify old email when email change is initiated 2024-04-26 21:02:01 -04:00
Nariman Jelveh fd59a6c994 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-26 15:36:22 -07:00
Nariman Jelveh cb4776cc0e do not append question mark to app URL if there is no query params to append 2024-04-26 15:36:15 -07:00
Eric Dubé 2ee00ca8e6 Revert "fix(security): Prevent email enumeration" (#351) 2024-04-26 18:22:14 -04:00
Nariman Jelveh a3ec7bb5ad Fix the issue with context submenu not closing parent menu when clicked 2024-04-25 23:14:39 -07:00
Nariman Jelveh faa72fd97c Update UIWindow.js 2024-04-25 23:10:03 -07:00
Nariman Jelveh 378b87459a Add robust hostname comparison for when declaring an environment as GUI 2024-04-25 17:51:20 -07:00
KernelDeimos 30f17ade3a fix: use primary read in signup 2024-04-25 19:46:39 -04:00
KernelDeimos ecec8bf75d Use pread for signup page 2024-04-25 19:44:06 -04:00
KernelDeimos 736ebb6f28 Improve server health service 2024-04-25 19:39:18 -04:00
Nariman Jelveh 928dd90f61 Merge pull request #346 from youngsiiimba/main
fix(security): Prevent email enumeration
2024-04-25 14:59:56 -07:00
KernelDeimos eb166a67a9 fix(security): Fix session revocation 2024-04-25 16:19:46 -04:00
Nariman Jelveh 51a6d1ea1d Allow the <p> tag in UIAlert body 2024-04-25 13:19:03 -07:00
Nariman Jelveh 3cce0e88df Revert "Allow the <p> tag in UIAlert body"
This reverts commit e2dcc813ec.
2024-04-25 13:18:37 -07:00
Nariman Jelveh e2dcc813ec Allow the <p> tag in UIAlert body 2024-04-25 13:18:28 -07:00
Nariman Jelveh a572a0a640 Merge pull request #341 from Xiayucheng1212/pass_locale
Pass locale to the iframe url whenever accessing an app
2024-04-25 13:14:16 -07:00
Nariman Jelveh c4b2d9861f Clean up some of the unnecessary console warnings 2024-04-25 13:11:11 -07:00
Simba Chawanda ed70314686 fix(security): Prevent email enumeration 2024-04-25 09:27:37 +02:00
Nariman Jelveh f5f35f2c37 Phase out openItem in IPC
also fix the issue with directories being opened with notepad after setting notepad as default app for files without extensions.
2024-04-24 23:12:57 -07:00
KernelDeimos ccf1afc93c feat(security): add ip rate limiting 2024-04-24 22:35:40 -04:00
KernelDeimos 7800ef6102 fix(security): skip cache when checking old passwd 2024-04-24 22:28:27 -04:00
Nariman Jelveh 25eea41f60 Keep track of app_instance_ids 2024-04-24 17:57:30 -07:00
Nariman Jelveh c21c16026b Update ko.js 2024-04-24 14:43:07 -07:00
KernelDeimos 74e9270d58 Fix 2024-04-24 16:16:31 -04:00
KernelDeimos b2e72adba9 Add ratelimit for /confirm-email 2024-04-24 16:12:09 -04:00
KernelDeimos 1eac147918 Add ratelimit for /contactUs 2024-04-24 16:09:04 -04:00
スーチ・ファトマワティ 3f6f4bb4c0 fix(security): update follow-redirects
When using axios, its dependency follow-redirects only clears authorization header during cross-domain redirect, but allows the proxy-authentication header which contains credentials too.

## Steps To Reproduce & PoC
```js
const axios = require('axios');

axios.get('http://127.0.0.1:10081/', {
 headers: {
 'AuThorization': 'Rear Test',
 'ProXy-AuthoriZation': 'Rear Test',
 'coOkie': 't=1'
 }
})
 .then((response) => {
 console.log(response);
 })
```
When I meet the cross-domain redirect, the sensitive headers like authorization and cookie are cleared, but proxy-authentication header is kept.

```diff
- removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
+ removeMatchingHeaders(/^(?:authorization|proxy-authorization|cookie)$/i, this._options.headers);
```
CWE-200
`CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N`
CVE-2024-28849
2024-04-24 15:23:47 -04:00
Sam Atkins a8d1d3b87a docs: Add help text to dcall utility (#335) 2024-04-24 15:21:31 -04:00
Nariman Jelveh fb3dfc5672 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-24 12:06:16 -07:00
Nariman Jelveh cdd0231a76 translation fix 2024-04-24 12:06:05 -07:00
Eric Dubé e9e43c059a Merge pull request #342 from brhahlen/docker-ci-improvements
Update Docker CI
2024-04-24 15:04:29 -04:00
Nariman Jelveh 548e975cac remove unused imports, sanitization, and validation of input 2024-04-24 10:05:53 -07:00
Sam Atkins cf0eee1fa3 feat: Add command names to phoenix tab-completion
Gives CommandProviders a `complete(query, {ctx})` method where they can provide completed command names, and then make use of this in CommandCompleter.

Supported CommandProvider sources:
- Shell built-ins (was supported previously)
- PATH executables (when running under Node)
- Puter app names (when running in Puter)

Script filenames are not yet supported.
2024-04-24 15:08:54 +01:00
Sam Atkins dc5b010d09 feat: Allow querying puter-apps driver by partial app names 2024-04-24 15:08:54 +01:00
Sam Atkins a854a0dc0a feat: Implement 'Like' predicate in entity storage
This acts like the SQL 'LIKE' keyword, allowing partial string matches.
2024-04-24 15:08:54 +01:00
Sam Atkins d733119456 fix: Make PathCommandProvider reject queries with path separators
`../bin/foo` should only find `foo` relative to the current working
directory, not to directories in PATH.

Also switch to using the Node path library since PathCommandProvider is
Node-only, and this means getting the correct path separator and
delimiter values on Windows.
2024-04-24 11:45:21 +01:00
Sam Atkins 670673ab8d Rename FooCompleter js files to match FooCommandProvider file names 2024-04-24 11:19:25 +01:00
Ben Hählen 028b37b9d4 Update Docker CI 2024-04-24 11:29:44 +02:00
Xiayucheng1212 916e1bb95c Add local to url 2024-04-24 16:40:42 +08:00
Nariman Jelveh c9e8207e4b Clean up the console warninf message 2024-04-23 23:53:15 -07:00
Nariman Jelveh aef6df048c allow the <strong> tag in UIAlert 2024-04-23 23:06:04 -07:00
Nariman Jelveh f8b2b18185 Update en.js 2024-04-23 22:49:16 -07:00
Nariman Jelveh ce411ed728 Perform more advanced input and string sanitization and validation for performance and security 2024-04-23 22:46:33 -07:00
Nariman Jelveh 9859a32e15 Deprecate and remove UIWindowConfirmDownload 2024-04-23 16:35:28 -07:00
Nariman Jelveh 3be7af8fb8 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-23 16:26:07 -07:00
Nariman Jelveh 5538649125 Update UIAlert.js 2024-04-23 16:25:57 -07:00
Eric Dubé 97ee951b1f Merge pull request #339 from HeyPuter/eric/rate-limits
Add ip rate limiting to some endpoints
2024-04-23 19:24:17 -04:00
KernelDeimos 44aac16991 Add ip rate limiting 2024-04-23 19:13:37 -04:00
Nariman Jelveh ab5fee1562 deprecate UIWindowGetCopyLink as it's not supported by the backend 2024-04-23 15:43:55 -07:00
KernelDeimos 65a73b5b45 Rename workspace modules to avoid confusion 2024-04-23 04:06:15 -04:00
KernelDeimos 74e213a534 fix(security): always use application/octet-stream 2024-04-22 23:54:03 -04:00
KernelDeimos f9d561d40b docs: document purpose of scary-looking token 2024-04-22 23:48:45 -04:00
Nariman Jelveh 5066128c72 Merge pull request #329 from Eric-Lighthall/desktop-bg-revert
feat: add option to change desktop background to default
2024-04-22 20:26:39 -07:00
Eric Dubé a2de5e3da2 Merge pull request #328 from HeyPuter/release-please--branches--main--components--puter.com
chore(main): release 2.2.0
2024-04-22 22:05:35 -04:00
github-actions[bot] 458f2eae4c chore(main): release 2.2.0 2024-04-23 02:03:34 +00:00
KernelDeimos c166560ff4 feat: add /healthcheck endpoint 2024-04-22 22:02:40 -04:00
Eric Lighthall 03f05f316f feat: add option to change desktop background to default
users can now select 'default' as their desktop background
2024-04-22 18:26:15 -07:00
Eric DubéandNariman Jelveh 331d9e7542 feat: allow apps to add a menubar via puter.js
* Begin work on menubar and dropdowns

* Improve menubar

* Fix pointer event behavior

* Fix labels

* Fix active button

* Eliminate flicker

* Update _default.js

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2024-04-22 20:38:16 -04:00
Eric Dubé ec31007c4b Update main.yml 2024-04-22 19:23:03 -04:00
Eric Dubé e615c7ee7f Update main.yml 2024-04-22 19:15:59 -04:00
Eric Dubé 35d4d4f755 Update main.yml 2024-04-22 19:14:21 -04:00
Eric Dubé 195468c4e1 Update main.yml 2024-04-22 19:11:51 -04:00
Eric Dubé 15f274e662 Create main.yml 2024-04-22 19:06:59 -04:00
Eric Dubé 7cb898457c Merge pull request #323 from HeyPuter/release-please--branches--main--components--puter.com
chore(main): release 2.1.1
2024-04-22 18:50:43 -04:00
github-actions[bot] aa4050ee32 chore(main): release 2.1.1 2024-04-22 22:42:20 +00:00
KernelDeimos f392de722a fix: test release-please action #4 2024-04-22 18:40:49 -04:00
Eric Dubé 07d95d5d3c Update release-please.yml 2024-04-22 18:34:13 -04:00
Eric Dubé 22c61d8221 Update release-please.yml 2024-04-22 18:18:35 -04:00
KernelDeimos 8fb0a66ef2 fix: test release-please action #3 2024-04-22 18:16:08 -04:00
KernelDeimos d5cd828cba chore: test release-please action #2 2024-04-22 18:12:35 -04:00
KernelDeimos 0119ae36a8 chore: test release-please action #1 2024-04-22 17:51:03 -04:00
Eric Dubé 87852d125f Only deploy docker image on release branch 2024-04-22 17:47:47 -04:00
Eric Dubé d3969b0122 Create release-please.yml 2024-04-22 17:46:40 -04:00
Nariman Jelveh 3cba4cab1e Disable iframing of the main domain using meta tags as well 2024-04-22 14:14:20 -07:00
Nariman Jelveh ef35a04c4a Disable iframing of the main domain 2024-04-22 14:09:32 -07:00
Eric Dubé 874928e845 Update bug_report.md 2024-04-22 16:39:47 -04:00
Eric Dubé c3d1574f8c Merge pull request #321 from HeyPuter/eric/batch-error-handling
Make errors in /batch more preemptive
2024-04-22 16:37:31 -04:00
KernelDeimos eee5c9e48b Cleanup 2024-04-22 16:29:12 -04:00
KernelDeimos 2f5780d1d1 Cleanup 2024-04-22 16:28:22 -04:00
Nariman Jelveh fa60f66057 Update helpers.js 2024-04-22 13:13:49 -07:00
KernelDeimos a741bd5419 Make errors in /batch more preemptive 2024-04-22 04:35:01 -04:00
KernelDeimos 4d2d4a7ca3 Fix 86888h53w 2024-04-21 22:06:36 -04:00
KernelDeimos 5c1e6ab16b Fix false-positive password recovery response 2024-04-21 18:28:58 -04:00
Nariman Jelveh f5f75dbef8 Add link to Bug Bounty program 2024-04-21 15:04:49 -07:00
Nariman Jelveh 6577051d64 Add Steam Deck to DiRP 2024-04-21 14:46:45 -07:00
KernelDeimos b2f5cc11b5 Fix dbrr reference 2024-04-21 17:10:18 -04:00
Nariman Jelveh a1252f66cc Update README.md 2024-04-21 12:50:58 -07:00
Nariman Jelveh e8d9e8b42b Update README.md 2024-04-20 20:34:52 -07:00
Nariman Jelveh ced7265eb0 Merge pull request #306 from zinreq/main
Do not show the "Change Password" option when user is temporary
2024-04-20 19:46:54 -07:00
zinreq 14098b2ff2 Do not show the "Change Password" option when user is temporary 2024-04-20 19:42:30 -07:00
Eric Dubé fb93a0863b Merge pull request #305 from HeyPuter/eric/support-levels
Document scope for fixes
2024-04-20 20:02:52 -04:00
KernelDeimos 4088bff216 Document scope for fixes 2024-04-20 19:57:40 -04:00
Nariman Jelveh 915152d3b9 Merge pull request #296 from Xiayucheng1212/keep_params
Keep the query params in the url started with '/app/*'
2024-04-20 16:45:05 -07:00
Nariman Jelveh 2ecea9a7b0 Prevent XSS by escaping user_set_url_params 2024-04-20 16:34:15 -07:00
Eric Dubé dc2a620b4e Merge pull request #304 from HeyPuter/eric/stdio-bridge/2
stdio-bridge 2
2024-04-20 19:29:15 -04:00
Nariman Jelveh 8648a303f1 use puter.js to retrieve server info 2024-04-20 15:29:33 -07:00
Nariman Jelveh 6a65ca4ebd Merge pull request #303 from Eric-Lighthall/login-server-info
Add server info to the login page for issue #257
2024-04-20 10:12:31 -07:00
KernelDeimos 58b83c27f2 Remove large log 2024-04-20 07:23:32 -04:00
Eric Lighthall 338d925bcc Fetch server info from versionservice.js module
Instead of directly fetching for the version info in UITabAbout.js, the module is now used for it
2024-04-20 02:24:45 -07:00
Eric Lighthall 7e2c4a0a1c Add server/version info on login page
The server/version info is under the forgot password section of the login page
2024-04-20 02:22:13 -07:00
Eric Lighthall 9822be5df4 Add version service module for fetching server information
this centralizes the handling of requests to get the server information
2024-04-20 01:58:12 -07:00
Nariman Jelveh cf5c62bcfc Update README.md to add more DiRPs 2024-04-19 23:52:41 -07:00
KernelDeimos 27553ef926 Cleanup 2024-04-19 23:35:56 -04:00
KernelDeimos 3f249fcc89 Fix pipes 2024-04-19 23:31:23 -04:00
KernelDeimos c3654ab148 Add more streaming fixes 2024-04-19 23:24:32 -04:00
KernelDeimos 0e9e8d41d9 Fix authorizer not defined 2024-04-19 17:12:15 -04:00
Sam Atkins 2f49c1c9b0 Remove a whole load of noisy log messages
These can be added back if and when we need them, but right now, it's
hard to follow console output with all this chatter. 😅
2024-04-19 17:29:26 +01:00
Sam AtkinsandKernelDeimos 072dbe8db5 Make BetterReader buffer and cancel, to fix stdin data loss
BetterReader.read_with_cancel() returns both the read promise, and a
function that can be used to cancel the read. A cancelled read is
placed back into the BetterReader's chunk buffer, to be consumed by the
next user that requests a read.

This is used by Coupler so that when the coupler is closed, its pending
read() call does not consume the next batch of input.

This fixes the problem we were having with child applications consuming
one chunk of stdin after they are closed, meaning the first key you
press after an app exits would disappear.

Co-authored-by: KernelDeimos <[email protected]>
2024-04-19 15:52:59 +01:00
KernelDeimos da208e23f5 Add a valve and internal pipe to commands 2024-04-19 15:52:59 +01:00
Sam Atkins 222a617c44 Phoenix: Use regular code path to run built-in apps
Now launchApp() can always be awaited, we can run built-in apps using
the same code path for other apps, and eventually have SIGINT close
them.
2024-04-19 15:52:59 +01:00
Sam Atkins e355c77a4a Phoenix: Wait for apps to finish executing, and connect stdio to them
After launching an app, if successful, we connect stdio streams to it,
and wait for it to exit before we return to the prompt.

stdio is implemented as regular AppConnection messages:
- stdin:  `{ $: 'stdin',  data: Uint8Array }` from phoenix -> child
- stdout: `{ $: 'stdout', data: Uint8Array }` from child -> phoenix

Terminal and Phoenix now communicate with each other using the same
style, instead of 'input' and 'output' messages. This will help with
eventually running subshells.

SIGINT currently is not sent. We also suffer from the same "one more
read from stdin happens after app exits" bug that's in
PathCommandProvider where I copied the stdin code from.
2024-04-19 15:52:59 +01:00
Sam Atkins 639653dac2 Report when a non-SDK app closes
puter.ui.launchApp() returns a Promise that needs to resolve whether the
app uses the Puter SDK or not. Non-SDK apps are tricky because they
don't send a READY message on startup, and we don't know in advance
whether an app will use the SDK or not.

This is a workaround to ensure that launchApp() always resolves. When an
app is closed, if it wasn't using the SDK, we send an artificial
notification that it launched, followed by an extra notification that
it has closed (because the original close notification was sent before
this point). This means any users of launchApp() can await it, and get
an AppConnection, and listen to the close event. They can't otherwise
interact with a non-SDK app because it will have closed already, but we
can improve this in the future without breaking the API.
2024-04-19 15:52:59 +01:00
Sam Atkins 0aa5543397 Let AppConnection know if its target app uses the Puter SDK
Apps are not required to use the Puter SDK. If they don't, then we can
still launch them, close them, and listen to their close event, but are
unable to send messages to them.
2024-04-19 15:52:59 +01:00
Sam Atkins dfdda4f3b9 Extract some helper functions for accessing a window/iframe by uuid 2024-04-19 15:52:59 +01:00
Eric Dubé 8cf58d7fc6 Merge pull request #299 from Eric-Lighthall/reduce-console-flicker
Optimize console redraw by tracking widget changes
2024-04-19 07:47:41 -04:00
Eric Lighthall 4783e3eae4 Optimize console redraw by tracking widget changes
Instead of redrawing the widget area every 2 seconds, only auto redraw when the widget area has changed, reducing unecessary redraw operations.
2024-04-19 00:48:36 -07:00
Eric Dubé 4931ad3960 Merge pull request #297 from AtkinsSJ/test-minimum-version
Make tests work in Node 16.x
2024-04-18 14:41:20 -04:00
Sam Atkins 5ad78a5ebb Expand supported versions that we test in CI
Phoenix now only requires 16.x or above, and so does Puter itself, so
let's include that, and also 18.x as the other LTS version.
2024-04-18 14:41:06 +01:00
Sam Atkins dc95f2e065 Phoenix: Support older Node versions in test harness
This brings Phoenix's minimum required version from 20.x down to 16.x.

ReadableStream.from() is deemed experimental, and requires Node 20.x
(or at least, something higher than 18.x). This was the only code that
made us require version 20.x.

ReadableStream and WritableStream are available from Node 16.5, but
require that they be explicitly imported.
2024-04-18 14:41:06 +01:00
KernelDeimos 0361ceba6c Normalize session objects to have both user_uid and user_id 2024-04-17 23:22:10 -04:00
KernelDeimos 4ecc7372f9 Fix issue with use_bundled_gui flag 2024-04-17 22:59:22 -04:00
KernelDeimos dbcd627815 Apply various small fixes 2024-04-17 20:57:59 -04:00
Nariman Jelveh 6061c81c36 Update get-launch-apps.js 2024-04-17 17:58:11 -07:00
Nariman Jelveh c1aee61da1 Update README.md 2024-04-17 10:14:10 -07:00
KernelDeimos f0d3346ca7 Update session.last_touch always 2024-04-17 13:03:32 -04:00
KernelDeimos e8ca6376be Avoid logging sensitive query params 2024-04-17 12:51:30 -04:00
KernelDeimos c48c134869 Remove verbose log 2024-04-17 12:42:12 -04:00
KernelDeimos 49e334521d Update timers 2024-04-17 12:41:43 -04:00
Eric Dubé 04a641adc2 Merge pull request #291 from AtkinsSJ/test-submodules
Re-enable Phoenix tests
2024-04-17 10:08:43 -04:00
Eric Dubé 2210652643 Merge pull request #295 from AtkinsSJ/remove-phoenix-css
Phoenix: Remove unwanted CSS includes
2024-04-17 10:07:33 -04:00
Xiayucheng1212 8713db3d55 Fix params lost 2024-04-17 19:45:01 +08:00
Sam Atkins f2e8b5ee3e Phoenix: Remove unwanted CSS includes 2024-04-17 11:05:03 +01:00
KernelDeimos 7e0c6c6470 Fix last_activity_ts 2024-04-16 19:30:30 -04:00
KernelDeimos 19c49db538 Improve sessions 2024-04-16 18:57:02 -04:00
Sam Atkins ea40ac1e53 Re-enable Phoenix tests
This also runs the tests for contextlink, which I think we previously
never ran. I don't see any other packages that define an `npm test`
command. Having to manually list all the sub-package test directories in
the top-level package.json is a bit unfortunate, but it works.

For Puter itself we support Node 16.x IIRC, but Phoenix requires at
least 20.x currently.
2024-04-16 13:57:02 +01:00
KernelDeimos 653898b463 Report proper error when an operation is invalid 2024-04-15 22:27:03 -04:00
KernelDeimos c07d0a2bc7 Set NO_VAR_RUNTIME in Dockerfile 2024-04-15 20:47:27 -04:00
KernelDeimos 9bb221a0d7 Fix Dockerfile 2024-04-15 19:03:00 -04:00
Eric Dubé e4f2c4a28b Merge pull request #280 from vineeth-vk11/#206
fixing on conflict issue in sqlite kv write
2024-04-15 17:55:52 -04:00
Eric Dubé 3a4858b83c Merge pull request #286 from AtkinsSJ/background-settings
Settings: Organise code to be grouped by tab, and add desktop background picker
2024-04-15 17:55:09 -04:00
KernelDeimos 826ea36502 Add use_bundled_gui option 2024-04-15 17:50:44 -04:00
KernelDeimos 397819d45e Add missing endpoint /down 2024-04-15 16:38:03 -04:00
KernelDeimos 66fecf88ef Fix funny context menu on task manager 2024-04-15 15:58:07 -04:00
KernelDeimos e8dc220981 This is 2.1.0 I decided 2024-04-15 15:37:13 -04:00
KernelDeimos 1c2b05d8f6 Fix phoenix for auto ports 2024-04-15 15:34:58 -04:00
KernelDeimos f3495f3098 Fix xterm.css not loading 2024-04-15 14:46:16 -04:00
KernelDeimos 081b093e7e Add missing asset for xterm, fix SDK url 2024-04-15 14:43:15 -04:00
KernelDeimos 4d30753958 Fix more phoenix dev issues 2024-04-15 14:25:40 -04:00
KernelDeimos c72e0cb0e0 Fix phoenix watcher 2024-04-15 14:08:50 -04:00
KernelDeimos 25f8dbf120 Add postinstall for phoenix 2024-04-15 14:02:49 -04:00
Sam Atkins 868202ba41 Settings: Add desktop-background setting to 'Personalization' tab 2024-04-15 17:41:19 +01:00
Sam Atkins c6b0ed32bf Settings: Move 'Clock' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins 17adef11a6 Settings: Move 'Language' tab into its own file
Also implement an optional `on_show` callback for settings tabs, to
support the "select and clear the search field" behaviour we had before.
2024-04-15 17:41:19 +01:00
Sam Atkins 6d1c807879 Settings: Move 'Personalization' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins 0ed5b20627 Settings: Move 'Account' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins f5175941d9 Settings: Move 'Usage' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins e2f048ec2d Settings: Move 'About'-specific logic and data into UITabAbout.js
Keeping all the logic and data for the tab together should make it
easier to modify.
2024-04-15 17:41:19 +01:00
KernelDeimos 2717444c29 Oops 2024-04-15 12:17:09 -04:00
KernelDeimos b21755b5a3 Fix casualty of phoenix due to Docker naming conventions 2024-04-15 12:12:28 -04:00
KernelDeimos 37ff97b52f Thanks minify 2024-04-15 03:59:39 -04:00
Eric Dubé b897598fac Merge pull request #282 from HeyPuter/eric/task-manager
Add a task manager
2024-04-15 03:53:51 -04:00
Eric Dubé 95cb92abed Remove outdated information 2024-04-15 03:50:46 -04:00
KernelDeimos 5730dc642a Add process ending and i18n 2024-04-15 03:37:04 -04:00
KernelDeimos 7c2a3b4612 Portal shows up as 'app' 2024-04-15 02:12:39 -04:00
Nariman Jelveh dbf796d698 Update index.js 2024-04-14 21:27:25 -07:00
Nariman Jelveh 7f739a53f8 Merge pull request #281 from HeyPuter/change-email-feature
Change email feature
2024-04-14 21:10:57 -07:00
Nariman Jelveh 2dbde52338 live-update email address after change 2024-04-14 21:09:41 -07:00
KernelDeimos 61f1caa122 Add type column 2024-04-14 23:58:14 -04:00
Nariman Jelveh 695d7b8654 Update UIDesktop.js 2024-04-14 20:53:31 -07:00
KernelDeimos 6e7fd2ca95 Add polling 2024-04-14 23:52:53 -04:00
KernelDeimos 79bfcf226b Integrate ProcessService with task manager 2024-04-14 23:52:53 -04:00
KernelDeimos 9d9e091a7a Add process management 2024-04-14 23:52:53 -04:00
KernelDeimos be1bb6bc06 Improve task manager style 2024-04-14 23:52:53 -04:00
KernelDeimos d39bb412f3 Begin work on task manager 2024-04-14 23:52:53 -04:00
KernelDeimos e71b586fe5 Invalidate cached user when the user's email address is changed 2024-04-14 23:50:39 -04:00
KernelDeimos 2fcac12340 Fixg 2024-04-14 23:24:47 -04:00
KernelDeimos 0847395c92 Socket 2024-04-14 23:10:23 -04:00
Nariman Jelveh 49c3df2328 allow child windows to center relative to parent window 2024-04-14 20:04:27 -07:00
KernelDeimos 58192cacb3 Try again 2024-04-14 23:00:07 -04:00
KernelDeimos b81284e2c6 Pass the RIGHT token to email 2024-04-14 22:49:51 -04:00
KernelDeimos 5b39e39e1f Use jwt for email change confirmation 2024-04-14 22:44:04 -04:00
KernelDeimos b944217410 Fix 2024-04-14 22:29:54 -04:00
KernelDeimos dca7304be9 Remove requirement of auth from email confirm 2024-04-14 22:23:42 -04:00
Nariman Jelveh 61a4b10adf add i18n text 2024-04-14 19:14:33 -07:00
KernelDeimos 231878266c Fix 2024-04-14 22:08:31 -04:00
KernelDeimos 51bf8fdde6 Fix 2024-04-14 21:41:08 -04:00
KernelDeimos 18134629d2 Move 2024-04-14 21:37:12 -04:00
KernelDeimos f6b737e45d Add confirmation email for email change 2024-04-14 21:33:15 -04:00
KernelDeimos 3b7be8a719 Add delete-own-user 2024-04-14 21:32:43 -04:00
Nariman Jelveh aae1d194c7 wip 2024-04-14 17:43:20 -07:00
KernelDeimos ef0da306a8 Fix change_email 2024-04-14 20:35:34 -04:00
Nariman Jelveh bfaaa914f1 wip 2024-04-14 17:30:22 -07:00
Nariman Jelveh 2f101c4a39 close #271 2024-04-14 17:10:46 -07:00
Nariman Jelveh 765eb43568 Disable manual arrangement in Explore 2024-04-14 12:50:28 -07:00
Nariman Jelveh aa61e005e5 Merge pull request #279 from hasanbeder/main
Translated Turkish language file
2024-04-14 09:53:59 -07:00
Nariman Jelveh 5b2e2b037b Update tr.js 2024-04-14 09:50:21 -07:00
Nariman Jelveh bcfd685826 Update translations.js 2024-04-14 09:48:43 -07:00
vineethvk11 5d8d25f370 fixing on conflict issue in sqlite kv write 2024-04-14 16:39:29 +05:30
hasanbeder 6679318207 Translated Turkish language file
This commit includes the Turkish language file with the translations. 🇹🇷
2024-04-14 13:12:56 +03:00
Nariman Jelveh 255e80d077 Make Puter.js verbosity optional via debug flag. 2024-04-13 17:31:29 -07:00
KernelDeimos 965d99d137 Fix socket auth 2024-04-13 17:19:12 -04:00
Nariman Jelveh 3b65523da9 separate refresh_item_container into a module 2024-04-13 13:41:15 -07:00
Nariman Jelveh 3cfee32ae0 Update helpers.js 2024-04-13 12:28:28 -07:00
Eric Dubé 497c633b8a Merge pull request #227 from MohamedElashri/main
Add requirements for multi-platform docker build to the CI
2024-04-13 14:58:45 -04:00
KernelDeimos df45e22813 Make node-pty not required 2024-04-13 13:56:57 -04:00
KernelDeimos 199b68a964 Highlight current session 2024-04-13 02:30:48 -04:00
Nariman Jelveh 8db8ec3574 Update Apps.js 2024-04-12 22:04:28 -07:00
KernelDeimos 4a36670417 Update README.md files for monorepo'd projects 2024-04-12 23:54:41 -04:00
KernelDeimos 77ac503bfc Edit phoenix README.md 2024-04-12 23:49:43 -04:00
Nariman Jelveh be55e447bb fix issue with two session managers on top of each other 2024-04-12 20:43:15 -07:00
KernelDeimos 00e9f922c0 Fix target version 2024-04-12 23:16:49 -04:00
KernelDeimos 361e51060a Update apps 2024-04-12 22:03:40 -04:00
Eric Dubé fbbc73308e Merge pull request #274 from HeyPuter/eric/builtin-apps
Move terminal and phoenix into main repo
2024-04-12 21:54:47 -04:00
KernelDeimos a31e4c19cb Update package-lock.json 2024-04-12 21:51:49 -04:00
Nariman Jelveh b69a85f10e Merge pull request #273 from Hiya-its-Aya/dark-mode
White text for themes
2024-04-12 18:30:15 -07:00
KernelDeimos d919b1f312 Register terminal and phoenix builtins 2024-04-12 20:56:16 -04:00
KernelDeimos cb81579c53 Copy over phoenix 2024-04-12 20:53:44 -04:00
KernelDeimos 0306a395a2 Copy over terminal 2024-04-12 20:53:32 -04:00
KernelDeimos 5fbbfb4c18 Enable background and builtin apps 2024-04-12 20:52:57 -04:00
Aya Moosa b725c4c7b4 removed commented code causing translation error 2024-04-12 14:39:46 -07:00
Aya Moosa 24e3ec89f3 added white text to brodacast 2024-04-12 14:28:15 -07:00
Aya Moosa f8d3fdbefb merge 2024-04-12 14:16:26 -07:00
Nariman Jelveh 352f1bc23e Update README.md to add link to fridge running Puter. 2024-04-12 13:59:59 -07:00
Nariman Jelveh 413cb79683 Merge pull request #269 from secondtruth/patch/translation-de
Update German translation
2024-04-12 13:26:35 -07:00
Christian Neff d06f856e46 Update German translation 2024-04-12 22:00:42 +02:00
KernelDeimos 09c3cc6db1 Fix error when session not found 2024-04-12 01:22:33 -04:00
Eric Dubé eb96dd952b Merge pull request #267 from HeyPuter/eric/session-fixes
session management fixes
2024-04-12 00:29:26 -04:00
KernelDeimos 1da3a769c4 Use localstorage instead of cookie for list-sessions 2024-04-12 00:19:07 -04:00
KernelDeimos 356a3284fa Fix mysql incompatibility 2024-04-12 00:10:56 -04:00
KernelDeimos 0eedcf567e Apply some fixes 2024-04-11 23:48:17 -04:00
KernelDeimos f4f58dbfb9 Fix destructuring 2024-04-11 23:28:40 -04:00
Eric Dubé 8135e076c2 Merge pull request #266 from HeyPuter/eric/session-updates
session management
2024-04-11 22:04:07 -04:00
Eric Dubé 22b3415866 Merge pull request #265 from HeyPuter/eric/puter-dot-js
puter.js
2024-04-11 21:59:46 -04:00
KernelDeimos 5effca4bbc Add missing i18n key 2024-04-11 21:57:26 -04:00
KernelDeimos aa14541e50 Update package-lock.json for npm ci 2024-04-11 21:54:50 -04:00
KernelDeimos 13525c85a0 -dot- 2024-04-11 21:46:43 -04:00
KernelDeimos 2f6f7e39bb Add timestamp 2024-04-11 21:41:19 -04:00
KernelDeimos 2d76025c9c Send cookie on token upgrade 2024-04-11 21:40:10 -04:00
KernelDeimos bb9edc4f65 Add automatic token migration 2024-04-11 21:33:44 -04:00
KernelDeimos afcd821f50 Update README.md 2024-04-11 19:40:50 -04:00
KernelDeimos b8e66cada9 Add puter.js 2024-04-11 19:07:00 -04:00
KernelDeimos fc5025a2a8 Simplify PuterVersionService 2024-04-11 14:37:34 -04:00
KernelDeimos e3d238f897 Do not use git to get version number 2024-04-11 13:57:40 -04:00
Nariman Jelveh 9ab3e3ccd8 Merge pull request #244 from HeyPuter/eric/host-storage
Display storage use of host/puter separately
2024-04-11 10:14:45 -07:00
Nariman Jelveh 7abf5faa3c fix missing translations 2024-04-11 10:13:52 -07:00
Nariman Jelveh 4052c7995c Merge pull request #260 from AtkinsSJ/fix-silly-mistakes
Fix permission check for closeApp message
2024-04-11 09:48:02 -07:00
Sam Atkins 776b6831f3 Fix permission check for closeApp message
Firstly, I was missing an `async` here, which somehow still worked for
me then, but produced errors for me when I tried it today.

Then, actually await the promise.

Finally, actually check the target's parent is us, and not just that it
has the attribute!

I don't know what was going on in my head that day. 🤦‍♂️
2024-04-11 17:21:23 +01:00
Nariman Jelveh a2d231dc23 Merge pull request #259 from PeterDaveHelloKitchen/zhtw
Add a simple Traditional Chinese translation
2024-04-11 09:02:20 -07:00
Peter Dave Hello 1aeedd8696 Add a simple Traditional Chinese translation 2024-04-11 20:03:13 +08:00
KernelDeimos 09bf422686 Add session manager ui 2024-04-11 00:29:39 -04:00
KernelDeimos 18b3e06fe8 Add session listing and revocation 2024-04-10 23:00:37 -04:00
KernelDeimos e436693d3e Improve session mgmt (part 1) 2024-04-10 21:54:16 -04:00
KernelDeimos eb66848aee Update database version when creating a new one 2024-04-10 12:25:44 -04:00
KernelDeimos 0eded34c8c Add indented logs and fix a bug 2024-04-10 12:22:21 -04:00
KernelDeimos 367c18bfc5 Add endpoint to list permissions 2024-04-10 12:16:08 -04:00
Eric Dubé 92dc0a7671 Merge pull request #255 from AtkinsSJ/appconnection-close
Notify apps when a child app closes, and let them close their children manually
2024-04-09 21:31:48 -04:00
Eric Dubé 8e553b4ee0 Merge pull request #252 from AtkinsSJ/broadcasts
Add a message broadcasting system
2024-04-09 21:29:46 -04:00
Sam Atkins 21c64e827b Add closeApp message
Sending a 'closeApp' message allows an app to close a target app, if it
has permission to do so. Currently, permission is granted if the
requesting app is the parent of the target app, or has godmode set.
2024-04-09 16:09:12 +01:00
Sam Atkins c69a0abfa9 Extract a window_for_app_instance() helper function 2024-04-09 15:55:14 +01:00
Sam Atkins cce6531d45 Notify parents/children when an app closes
Send an appClosed message with the instance ID of the app that was
closed. This will be picked up by Puter.js's AppConnection and reported
as a 'close' event.

To make this work, a `data-parent_instance_id` attribute is set on child
app windows. This is very similar to the `data-parent_uuid` attribute,
which tracks parent windows instead of parent app instances. (Dialogs
have a parent window, but are not apps, so don't have a parent app
instance.) The difference is subtle, and we may want to combine these in
the future, but currently closing an app will close any child windows,
which is not behaviour we want for child apps.
2024-04-09 15:55:14 +01:00
Sam Atkins 84a31b3520 Broadcast when the language changes
This is left open to future additions, by naming it 'locale', and having
the language just be an object field.

Side note, maybe we should have a LocaleService for this?
2024-04-09 10:44:51 +01:00
Sam Atkins 59cdb6e8c6 Broadcast when theme changes 2024-04-09 10:44:51 +01:00
Sam Atkins 068e620249 Add a message broadcasting service
A broadcast is a message sent to every running app that uses Puter.js.
Broadcasts have a name and a data payload, and are sent as a 'broadcast'
message.

Send a broadcast using:
`globalThis.services.get('broadcast').sendBroadcast(...)`

When doing so, you have the option to keep the broadcast message around,
so that it can be sent to any newly-launched apps. Sending another
broadcast with the same name will overwrite the previous one, so you
don't have to worry about flooding a new app with duplicates.
2024-04-09 10:44:51 +01:00
Aya Moosa 80aa87023e working white text, not perfect with all colors 2024-04-08 22:01:00 -07:00
Aya Moosa 626d63c91d working white text, not perfect with all colors 2024-04-08 22:00:12 -07:00
Aya Moosa 5bf0411015 got white text working, restets when other silders are used 2024-04-08 21:24:24 -07:00
Aya Moosa b2fcb8d104 started light text for color 2024-04-08 15:59:12 -07:00
KernelDeimos 79f98795c7 Fix version checker using later javascript features 2024-04-08 17:05:47 -04:00
Eric Dubé 24ad365047 Merge pull request #253 from AtkinsSJ/bad-config-login-error
Add an error message when login fails because of domain misconfiguration
2024-04-08 12:23:31 -04:00
Eric Dubé 72286fd642 Merge pull request #249 from AtkinsSJ/service-copyrights
Add some missing copyright notices
2024-04-08 12:22:15 -04:00
Mohamed Elashri a0f46c326a Add build stage and remove linux/arm/v7 2024-04-08 17:12:26 +02:00
Sam Atkins b1f2750cdb Add an error message when login fails because of domain misconfiguration
Previously, we just output whatever err.responseText was. However, that
has some downsides:

- If there's no responseText (as for when we can't find the domain) then
  the user gets a blank message.
- If it's a 404 error, the responseText includes the full HTML for
  Puter's 404 page, which we don't want to dump in the error box! This
  is unlikely to happen in practice, but was easy enough to cater for.

So, add a nicer message in those cases.

The misconfiguration message is taken from here:
https://github.com/HeyPuter/puter/issues/185#issuecomment-2037977592

Resolves #235.
2024-04-08 15:49:00 +01:00
Sam Atkins 8aee3f8174 Add some missing copyright notices 2024-04-08 11:10:39 +01:00
Nariman Jelveh ea61799b3d Merge pull request #240 from HeyPuter/eric/gui-personalization
Puter Theme Color Setting
2024-04-07 14:35:24 -07:00
KernelDeimos b1e6e0c25a Fix i18n 2024-04-07 17:27:09 -04:00
KernelDeimos f7916cfa74 Add option to reset colors 2024-04-07 17:19:47 -04:00
KernelDeimos 3f37ef2fad Fix i18n 2024-04-07 16:18:59 -04:00
KernelDeimos 3297940bab Improve dialog 2024-04-07 04:53:49 -04:00
KernelDeimos 821d33b8d8 Make opacity differences match prod 2024-04-07 04:39:08 -04:00
KernelDeimos 72129ca16f Make defaults consistent with original 2024-04-07 03:21:32 -04:00
KernelDeimos 12fa88b149 Save color settings 2024-04-07 03:15:45 -04:00
KernelDeimos c83069bd03 Add i18n items 2024-04-07 02:53:33 -04:00
KernelDeimos 5661605884 Add ui colors to settings window 2024-04-07 02:53:05 -04:00
KernelDeimos d1bbbb8e93 Use CSS variables 2024-04-07 02:34:04 -04:00
KernelDeimos 178f851684 Fix previous fix 2024-04-07 00:28:23 -04:00
KernelDeimos cb4b8c5914 Add minor fixes 2024-04-07 00:06:11 -04:00
KernelDeimos 8018a607a8 Add CSS 2024-04-07 00:05:54 -04:00
KernelDeimos dc5a7ca431 Display storage use of host/puter separately 2024-04-06 23:26:18 -04:00
Eric Dubé 95d33eab94 Merge pull request #238 from AtkinsSJ/app-ipc
Implement support for launching child apps, and IPC between a parent and its children
2024-04-06 07:51:17 -04:00
Sam Atkins 725cbf2e20 Add support for launching child apps
Calling `puter.ui.launchApp()` now treats the new app as a child of the
one that launched it.

A child app is given a `puter.parent_instance_id` URL param, containing
its parent's instance ID.

Previously, `launchApp()` would resolve as soon as the app was launched.
This commit changes that, so that it is notified after the child app
sends its READY event to Puter. This means that as soon as `launchApp()`
has completed, the child app is ready to receive messages. The downside
is that launching an app that does not include Puter.js will now not
cause a notification, so `await puter.ui.launchApp()` will not resolve
in that case.
2024-04-06 12:27:36 +01:00
KernelDeimos 674cebd9e1 Add Linux support to HostDiskUsageService 2024-04-06 05:33:46 -04:00
Eric Dubé 0dd66463df Merge pull request #241 from vineeth-vk11/#233
Implementing HostDiskUsageService removing diskusage dependency
2024-04-06 05:29:21 -04:00
KernelDeimos beeeb7bcbf Tiny fix 2024-04-06 05:08:38 -04:00
vineethvk11 bf4bc214b2 Implementing HostDiskUsageService removing diskusage dependency 2024-04-06 13:03:09 +05:30
KernelDeimos b99534ebdf Add WIP color sliders 2024-04-06 02:35:06 -04:00
Eric Dubé c6fb75c65f Merge pull request #231 from HeyPuter/eric/user-to-user-permissions
User-to-User Permission Granting
2024-04-05 23:11:32 -04:00
KernelDeimos 38e8b19b50 Cleanup 2024-04-05 23:05:20 -04:00
KernelDeimos 90ce840234 Add revoke-user-user endpoint 2024-04-05 23:01:50 -04:00
KernelDeimos fc6eda392b Allow granting user-to-user permissions 2024-04-05 22:11:36 -04:00
KernelDeimos 343edbff51 Use weak CORS policy for experimental_no_subdomain 2024-04-05 16:51:57 -04:00
KernelDeimos fe88880486 Add experimental_no_subdomain flag 2024-04-05 16:21:19 -04:00
KernelDeimos 1c2e4968e2 Remove console log 2024-04-05 14:38:50 -04:00
KernelDeimos f9b375a39b Fix case when main domain is a subdomain 2024-04-05 14:38:33 -04:00
KernelDeimos eb18e74e88 Add error when someone forgets npm install 2024-04-05 14:09:34 -04:00
Eric Dubé 487553a00c Merge pull request #237 from eltociear/patch-2
Update download.js
2024-04-05 13:32:05 -04:00
Sam Atkins c78927d5db Add messageToApp message
This lets apps communicate with each other, via Puter.

We probably want to limit this in some way, but for now, all apps are
allowed to send messages to any other apps.

The message is:
- `targetAppInstanceID`: The instance ID to send the message to
- `targetAppOrigin`: targetOrigin passed to postMessage(), in case we
  want to restrict which URL can receive the message
- `contents`: The message to send to the target
2024-04-05 16:38:12 +01:00
Ikko Eltociear Ashimine 26e9822344 Update download.js
minor fix
2024-04-06 00:22:22 +09:00
KernelDeimos 207fa139d4 Add user-to-user permissions table 2024-04-05 03:23:31 -04:00
Eric Dubé e2236d43fd Merge pull request #234 from vineeth-vk11/#80
fixing issues in copy while overwriting
2024-04-05 03:21:22 -04:00
vineethvk11 6006767a9f fixing issues in copy while overwriting 2024-04-05 09:11:39 +05:30
KernelDeimos 35abf9a6bc Stop printing default password in logs 2024-04-04 22:17:00 -04:00
KernelDeimos c3a4223bbf Add service to check EOL date of node 2024-04-04 22:10:56 -04:00
KernelDeimos 4a2fa5a29f Friendly node version errors 2024-04-04 21:39:32 -04:00
Mohamed Elashri 17ae6668b4 Add linux/arm/v7 again
We need to test if this is what causes the problem of the GitHub action getting stuck or `linux/arm/v6`
2024-04-05 01:10:47 +00:00
Mohamed Elashri 06a31fd67b Fix typo in arm64 namespace 2024-04-05 00:59:05 +00:00
Mohamed Elashri 1a13ef6921 remove linux/arm/v7,linux/arm/v6 emporarily 2024-04-05 00:55:44 +00:00
KernelDeimos 17a323298c Make dismiss command print what was dismissed 2024-04-04 20:46:03 -04:00
KernelDeimos 27c99fd90a Use OR IGNORE when sqlite 2024-04-04 20:02:35 -04:00
KernelDeimos 6c7175c109 NOOP legacy share fetch 2024-04-04 19:26:29 -04:00
KernelDeimos cdd9dbf748 Add quick doc about https 2024-04-04 19:08:45 -04:00
Eric Dubé 1b72b80241 Merge branch 'main' into main 2024-04-04 18:43:39 -04:00
Eric Dubé be53a9472a Update docker-image.yaml 2024-04-04 18:39:53 -04:00
Mohamed Elashri accdec3af4 handle linking to python binary gracefully 2024-04-04 21:51:39 +00:00
Mohamed Elashri 95b6dbd140 Add python3 to use node-gyp to allow native cross platform build
python3 would be required by node-gyp to natively build node add-on. This is required if we build for multi-platform
2024-04-04 21:47:29 +00:00
KernelDeimos 08838c989e Fix fragmented if..else seq (fix app tokens) 2024-04-04 17:44:54 -04:00
Mohamed Elashri 74bff84226 Remove unpopular archs
For now, we need to stick to the most used archs for resources and build time reasons.
2024-04-04 21:35:22 +00:00
Mohamed Elashri b1a3124fcc Add requirements for multi-platform docker build to the CI 2024-04-04 22:58:00 +02:00
Eric Dubé 3e1c7eb434 Merge pull request #223 from vineeth-vk11/#211
removing storage limit for self hosters
2024-04-04 16:12:31 -04:00
KernelDeimos 2125367683 Avoid predicate.values not iterable error 2024-04-04 14:20:30 -04:00
KernelDeimos 809e33b053 Remove unused code 2024-04-04 14:18:34 -04:00
KernelDeimos 0efe163591 Update README.md 2024-04-04 13:56:33 -04:00
Eric Dubé e8935f5582 Add many platforms arbitrarily
Related to #214; added additional architectures which may or may not work. I'd rather someone find out it doesn't work then for them to be blocked from even trying.
2024-04-04 13:47:24 -04:00
vineethvk11 0da9e1fab3 removing storage limit for self hosters 2024-04-04 22:31:37 +05:30
Eric Dubé 802370eb9d Fix heading level 2024-04-04 02:14:36 -04:00
KernelDeimos 4e722b47b5 Document pub_port, which wasn't documented before 2024-04-03 22:11:52 -04:00
KernelDeimos b055c5cdad Fix change_username 2024-04-03 22:06:06 -04:00
KernelDeimos b7a1f21e31 Fix puter sites errors 2024-04-03 22:05:33 -04:00
KernelDeimos a04cac60e6 Fix db migration error in SQLES 2024-04-03 17:38:42 -04:00
KernelDeimos 274b69d017 Fix /file and /setItem 2024-04-03 17:21:25 -04:00
Nariman Jelveh 5fab338ba1 Merge pull request #219 from HeyPuter/eric/2024-04-02/display-directory-load-error
Display error in directory when readdir fails
2024-04-02 15:44:44 -07:00
KernelDeimos 6cd77384a5 Update default text for explorer-error-message 2024-04-02 16:50:22 -04:00
KernelDeimos 5290d78e20 Display error in directory when readdir fails 2024-04-02 16:46:34 -04:00
Eric Dubé 2ce02db1b5 Update issue templates 2024-04-02 05:03:39 -04:00
Eric Dubé fff46a6b63 Update issue templates 2024-04-02 04:54:33 -04:00
KernelDeimos 369037e269 Fix incorrect asset urls 2024-04-02 04:19:22 -04:00
KernelDeimos 6f7264b60b Fix logout for invalid sessions 2024-04-02 04:19:12 -04:00
KernelDeimos 9881fecacd Fix error caused by fixing kv 2024-04-02 03:40:58 -04:00
KernelDeimos cf9338c35f Document different configuration locations 2024-04-02 02:14:59 -04:00
KernelDeimos a9947ad97f Update README.md 2024-04-02 02:09:36 -04:00
Eric Dubé ac2e3e2873 Merge pull request #212 from shuguet/main
fix: Fix permission errors when running Docker. Update Docker Compose & Docker instructions
2024-04-02 02:02:46 -04:00
Sylvain Huguet 8f4eb5627b Update instructions & docker-compose to reflect production paths 2024-04-02 07:45:14 +02:00
Sylvain Huguet e4bd62b84c Fix README instructions following path changes 2024-04-02 07:34:55 +02:00
Sylvain Huguet 0e033348f0 Fix permission errors when running Docker. Update Docker Compose & Docker instructions 2024-04-02 07:26:44 +02:00
KernelDeimos 0651aab1be Fix DBKVStore value format 2024-04-02 00:47:14 -04:00
KernelDeimos f8a7f1c1f9 Update README.md 2024-04-02 00:33:02 -04:00
KernelDeimos c90931d004 Fix docker-compose.yml 2024-04-02 00:25:29 -04:00
KernelDeimos a973f66092 Only load from source in dev environment 2024-04-01 22:26:09 -04:00
KernelDeimos 5d81ff4cbe Fix dev console bar when columns has small value 2024-04-01 22:01:34 -04:00
KernelDeimos 7442b48157 Fix undefined instead of null in db query 2024-04-01 19:41:16 -04:00
KernelDeimos 59003a9ab9 Make dev-console use in WebServerService optional 2024-04-01 19:40:59 -04:00
KernelDeimos 40c2e3f442 Add April-1st-appropriate commit message guidelines 2024-04-01 19:33:11 -04:00
KernelDeimos 65b61fc90d Remove unused variable 2024-04-01 17:24:48 -04:00
KernelDeimos 05c6cd6c3d Separate default user into SelfhostedModule 2024-04-01 17:24:07 -04:00
Eric Dubé 15fcc5680f Merge pull request #195 from shuguet/main
feat: Add support for running Puter self-hosted using the automatically built Docker image
2024-04-01 15:06:23 -04:00
Eric Dubé fdd9f30c39 Merge branch 'main' into main 2024-04-01 15:06:16 -04:00
Nariman Jelveh 0049c9ef00 Merge pull request #205 from AtkinsSJ/fix-i18n-typo
Fix issues with translation keys, and check these in CI
2024-04-01 11:18:43 -07:00
Nariman Jelveh f097f2e10a Merge pull request #164 from vineeth-vk11/#141
removing html inside translation strings
2024-04-01 11:03:55 -07:00
Nariman Jelveh 4009f4f331 Merge branch 'main' into #141 2024-04-01 11:02:37 -07:00
Sam Atkins 8f8b7f0fbf Check that all uses of i18n() use keys that exist
If code uses `i18n('foo')` and 'foo' is not in the dictionary for the en
translation, then this script will now report it as an error. This has
already helped catch a few mistakes.
2024-04-01 12:12:31 +01:00
Sam Atkins 29b3b4ecba Add or correct missing i18n keys
'save_account_to_publish' isn't used anywhere, so I assume that
'save_account_to_publish_website' is supposed to use that.
2024-04-01 12:10:31 +01:00
Sam Atkins b111e05ef7 Fix typo in 'change_always_open_with' i18n key 2024-04-01 12:00:58 +01:00
Sam Atkins c2f73c37c5 Correct capitalisation of i18n() keys
Found by searching for `i18n\(\'[^\']*[A-Z]+[^\']*\'\)`
2024-04-01 11:26:07 +01:00
KernelDeimos 92b3f4ff76 Default user random pass, sqlite query patches 2024-04-01 01:23:53 -04:00
KernelDeimos 1cdda3dda8 Document default user 2024-03-31 22:47:13 -04:00
KernelDeimos a8a03d3f87 Add some config documentation 2024-03-31 22:42:11 -04:00
KernelDeimos 5eebc9a5de Update ports for repo docker 2024-03-31 21:48:42 -04:00
Sylvain Huguet cc648be854 Re-enable healthchecks, adjusted intervals & start-time 2024-04-01 02:07:44 +02:00
Sylvain Huguet 483e2835c4 Disable healthcheck in Dockerfile as well 2024-03-31 11:34:03 +02:00
Sylvain Huguet daa90286d3 Update README instruction to run either with pure Docker, or with Docker Compose 2024-03-31 11:30:12 +02:00
Sylvain Huguet 5e1d6a7db3 Disable healthcheck until we know the proper URL to call/check 2024-03-31 11:19:35 +02:00
Sylvain Huguet ab4f222e92 Add support for self-hosting in Docker 2024-03-31 11:18:03 +02:00
vineeth kumar 5da46a15fb Merge branch 'main' into #141 2024-03-31 13:02:11 +05:30
vineethvk11 9438355a36 removing html inside translation strings 2024-03-31 12:53:53 +05:30
575 changed files with 54141 additions and 5081 deletions

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
# === FOR EMPTY COMMITS ===
# Select reason for empty commit:
- [ ] Add conventional commit message for changelog
- [x] Forgot to use conventional commit style
# Increment this value if nothing above was changed
0
+1
View File
@@ -1,3 +1,4 @@
.dockerignore
Dockerfile
node_modules
/puter
+1 -1
View File
@@ -1 +1 @@
PORT=4000
PORT=4000
+25
View File
@@ -0,0 +1,25 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Issue Description**
**Steps to Reproduce**
**Expected & Actual Behavior**
**Addition Information or Screenshots (if applicable)**
**Deployment**
- [ ] Production (puter.com)
- [ ] Development (`npm run start`)
- [ ] Docker (via `docker run`)
- [ ] Docker (via `docker-compose`)
**Puter version (if accessible)**
> Click the profile button on the top-right, then "Settings". The version number will be printed at the bottom
+10
View File
@@ -0,0 +1,10 @@
---
name: Driver Request
about: Request a driver on Puter
title: ''
labels: ''
assignees: ''
---
> Drivers are services that apps on Puter can use. For example, drivers support many of the features in the [Puter SDK](https://docs.puter.com/). If you're not sure if what you're suggesting is a driver, you should use the "Feature Request" template instead.
+10
View File
@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest an idea for Puter
title: ''
labels: idea
assignees: ''
---
@@ -0,0 +1,10 @@
---
name: Idea for Improvement
about: An enhancement for an existing feature on Puter
title: ''
labels: enhancement
assignees: ''
---
+31
View File
@@ -0,0 +1,31 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
name: Node.js CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x, 18.x, 20.x, 21.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
+15 -10
View File
@@ -5,8 +5,10 @@ name: Docker Image CI
# branch called `main`.
on:
push:
branches: ['main']
tags:
- '*.*.*'
# branches:
# - 'release'
# Defines two custom environment variables for the workflow. These are used
# for the Container registry domain, and a name for the Docker image that
@@ -41,6 +43,12 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about)
# to extract tags and labels that will be applied to the specified image.
# The `id` "meta" allows the output of this step to be referenced in
@@ -50,16 +58,10 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
type=sha
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
# This step uses the `docker/build-push-action` action to build the
# image, based on your repository's `Dockerfile`. If the build succeeds,
@@ -73,7 +75,10 @@ jobs:
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
context: .
push: true
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
@@ -1,6 +1,6 @@
# This workflow runs the tools/check-translations.js script to make sure that the translation data is valid.
# Lint PRs and pushes to the main branch
name: Check Translations
name: Lint
env:
NODE_VERSION: 21.x
@@ -13,7 +13,7 @@ on:
branches: [ "main" ]
jobs:
test:
build:
runs-on: ubuntu-latest
steps:
@@ -24,5 +24,10 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: ./package-lock.json
- run: npm ci
- run: npm run check-translations
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npx eslint
- name: Check translations
if: '!cancelled()'
run: npm run check-translations
+40
View File
@@ -0,0 +1,40 @@
name: Maintain Release Merge PR
on:
push:
branches:
- main
jobs:
update-release-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Git
run: |
git config user.name github-actions
git config user.email [email protected]
- name: Check for existing PR
id: find-pr
uses: juliangruber/find-pull-request-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: release
- uses: actions/checkout@v4
if: steps.find-pr.outputs.number == ''
with:
ref: release
- name: Reset release branch
if: steps.find-pr.outputs.number == ''
run: |
git fetch origin main:main
git reset --hard main
- name: Create/Update PR
if: steps.find-pr.outputs.number == ''
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update release branch
title: Merge Release Auto-PR
body: Merging this PR will invoke release actions
branch: auto-update/release
+18
View File
@@ -0,0 +1,18 @@
on:
push:
branches:
- main
permissions:
contents: write
pull-requests: write
name: release-please
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v4
with:
release-type: node
+19 -2
View File
@@ -1,11 +1,28 @@
# Misc
.DS_Store
# Dependencies
node_modules/
*.zip
*.tgz
license.config.json
license-header.txt
# Build Outputs
dist/
.vscode/
# VS Code IDE
.vscode/**/*
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/settings.json
!.vscode/tasks.json
# Local env files
.env
!.env.example
# this is for jetbrain IDEs
.idea/
.idea/
/puter
+7
View File
@@ -0,0 +1,7 @@
{
"cSpell.words": [
"dnsmasq",
"heyputer",
"Puter"
]
}
+66
View File
@@ -0,0 +1,66 @@
# Changelog
## 2.3.0 (2024-05-22)
### Features
* add /healthcheck endpoint ([c166560](https://github.com/HeyPuter/puter/commit/c166560ff4ab5a453d3ec4f97326c995deb7f522))
* Add command names to phoenix tab-completion ([cf0eee1](https://github.com/HeyPuter/puter/commit/cf0eee1fa35328e05aefc8a425b5977efe5f4ec9))
* add option to change desktop background to default ([03f05f3](https://github.com/HeyPuter/puter/commit/03f05f316f11e8afe5fcee40b2b80a0de5e6826f))
* allow apps to add a menubar via puter.js ([331d9e7](https://github.com/HeyPuter/puter/commit/331d9e75428ec7609394f59b1755374c7340f83e))
* Allow querying puter-apps driver by partial app names ([dc5b010](https://github.com/HeyPuter/puter/commit/dc5b010d0913d2151b4851f8da5df72d2c8f42e7))
* Display upload errors in UIWindowProgress dialog ([edebbee](https://github.com/HeyPuter/puter/commit/edebbee9e7e9efbb33bf709b637c103be40d15a8))
* Implement 'Like' predicate in entity storage ([a854a0d](https://github.com/HeyPuter/puter/commit/a854a0dc0aa79a31695db833184c5ca3698632a9))
* improve password recovery experience ([04432df](https://github.com/HeyPuter/puter/commit/04432df5540811710ce1cc47ce6c136e5453bccb))
* **security:** add ip rate limiting ([ccf1afc](https://github.com/HeyPuter/puter/commit/ccf1afc93c24ee7f9a126216209a185d6b4d9fe4))
* Show "Deleting /foo" in progress window when deleting files ([f07c13a](https://github.com/HeyPuter/puter/commit/f07c13a50cee790eec44bce2f6e56fbcbf73f9b0))
### Bug Fixes
* Add missing file extension to 0009_app-prefix-fix.sql in DB init ([a8160a8](https://github.com/HeyPuter/puter/commit/a8160a8cdcdd6aff98728a6f1643d93386e6bb5a))
* Add missing TextEncoder to PTT ([8d4a1e0](https://github.com/HeyPuter/puter/commit/8d4a1e0ed3872e2c82b9e4be9b6d8b359e9cea09))
* Correct APIError imports ([062e23b](https://github.com/HeyPuter/puter/commit/062e23b5c9673db1f8b0ff0469289d52dd1e3f99))
* Correct grep output when asking for line numbers ([c8a20ca](https://github.com/HeyPuter/puter/commit/c8a20cadbfd539d185d32f4558916825fcf265ba))
* Correct inverted instanceof check in SignalReader.read() ([d4c2b49](https://github.com/HeyPuter/puter/commit/d4c2b492ef4864804776d3cb7d24797fdc536886))
* Correct variables used in errors in sign.js ([fa7c6be](https://github.com/HeyPuter/puter/commit/fa7c6bee9699527028be0ae9759155bc67c52324))
* Eliminates duplicate translation keys ([5800350](https://github.com/HeyPuter/puter/commit/5800350b253994dea410afff64e3df2a171e7775))
* fix error handling for outdated node versions ([4c1d5a4](https://github.com/HeyPuter/puter/commit/4c1d5a4b6d009ce075897d499d3517219bd745a4))
* Fix phoenix app prefix and TokenService test ([afb9d86](https://github.com/HeyPuter/puter/commit/afb9d866b5091058711db931cde904947e661c15))
* increase QR code size ([d2de46e](https://github.com/HeyPuter/puter/commit/d2de46edfbc05d132d5c929f6935b82515fbbda0))
* Make PathCommandProvider reject queries with path separators ([d733119](https://github.com/HeyPuter/puter/commit/d73311945610417a1ebc7bb0723ced0a599594b4))
* Make url variable accessible to all users of it ([2f30ae7](https://github.com/HeyPuter/puter/commit/2f30ae7a825adcd8da95888c38fe39c34acee0ff))
* Only run Component initialization functions once ([5b43358](https://github.com/HeyPuter/puter/commit/5b43358219402bee3eadf4a0f184a4b924d3293b))
* Parse octal echo escapes ([6ad8f5e](https://github.com/HeyPuter/puter/commit/6ad8f5e06abd050d319271f818d72debf5bc8e44))
* reduce token lengths ([5a76bad](https://github.com/HeyPuter/puter/commit/5a76bad28dfd8ec89a309941e410a54927fae22d))
* reliability issue :bug: ([1d546d9](https://github.com/HeyPuter/puter/commit/1d546d9ef70ef9066ad5838e9782ae330d289f29))
* Remove null or duplicate app entries from suggest_app_for_fsentry() ([6900233](https://github.com/HeyPuter/puter/commit/6900233c5aaa2d1a49f495e9f9a060796757a91e))
* **security:** always use application/octet-stream ([74e213a](https://github.com/HeyPuter/puter/commit/74e213a534dbf2844c8cebeee7eb59ec70de306e))
* **security:** Fix session revocation ([eb166a6](https://github.com/HeyPuter/puter/commit/eb166a67a9f0caf4fd77f9e27dc8209c2fc51f4c))
* **security:** Move token for socket.io to request body ([49b257e](https://github.com/HeyPuter/puter/commit/49b257ecffbb1e12090b86a67528a5ad09da69db))
* **security:** Prevent email enumeration ([ed70314](https://github.com/HeyPuter/puter/commit/ed703146863f896df76c98fad7127c6748c0ef9b))
* **security:** skip cache when checking old passwd ([7800ef6](https://github.com/HeyPuter/puter/commit/7800ef61029c8d1ba47491b4028a0cb972298725))
* **Terminal:** Accept input from Chrome on Android ([4ef3e53](https://github.com/HeyPuter/puter/commit/4ef3e53de34f0097950a7e707ca2483863beafb5))
* test release-please action [#3](https://github.com/HeyPuter/puter/issues/3) ([8fb0a66](https://github.com/HeyPuter/puter/commit/8fb0a66ef21921990e564e5f61c0e80e7f929dc7))
* test release-please action [#4](https://github.com/HeyPuter/puter/issues/4) ([f392de7](https://github.com/HeyPuter/puter/commit/f392de722a5232b622ed91b656a31cdc443c2e84))
* typographical error :bug: ([2949f71](https://github.com/HeyPuter/puter/commit/2949f71691eb0a258888c5d2a5bb496d2fe64a23))
* typographical errors :bug: ([4d30740](https://github.com/HeyPuter/puter/commit/4d30740198402cd1cc61b9ea4c45e006b69ec87e))
* Use correct variable for version number ([52d5299](https://github.com/HeyPuter/puter/commit/52d52993744dffa9f7f59a232da5df9077560731))
* use primary read in signup ([30f17ad](https://github.com/HeyPuter/puter/commit/30f17ade3a893d2283316e581836607e2029f9b9))
## [2.2.0](https://github.com/HeyPuter/puter/compare/v2.1.1...v2.2.0) (2024-04-23)
### Features
* add /healthcheck endpoint ([c166560](https://github.com/HeyPuter/puter/commit/c166560ff4ab5a453d3ec4f97326c995deb7f522))
* allow apps to add a menubar via puter.js ([331d9e7](https://github.com/HeyPuter/puter/commit/331d9e75428ec7609394f59b1755374c7340f83e))
## [2.1.1](https://github.com/HeyPuter/puter/compare/v2.1.0...v2.1.1) (2024-04-22)
### Bug Fixes
* test release-please action [#3](https://github.com/HeyPuter/puter/issues/3) ([8fb0a66](https://github.com/HeyPuter/puter/commit/8fb0a66ef21921990e564e5f61c0e80e7f929dc7))
* test release-please action [#4](https://github.com/HeyPuter/puter/issues/4) ([f392de7](https://github.com/HeyPuter/puter/commit/f392de722a5232b622ed91b656a31cdc443c2e84))
+22
View File
@@ -57,6 +57,28 @@ See [doc/contributors/index.md](./doc/contributors/index.md) for more informatio
<br>
## Commit Messages
Use the imperative, as is the convention in the Linux kernel:
- correct: `Improve performance of readdir`
- incorrect: `Improved readdir`
- incorrect: `Improving readdir`
We have the following exceptions to this rule:
- If the commit message is in _past tense_, it's a shorthand for the following:
- `Apply changes that would be applied after one had <past tense message>`
- If the commit message is in _present tense_, it's shorthand for the following:
- `Apply changes that would be applied after <present-tense message>`
For example, the following are correct:
- `Improved readdir`
- interpret this as: `Apply changes that would be applied after one had improved readdir`
- `Improving readdir`
- interpret this as: `Apply changes that would be applied after improving readdir`
<br>
## Code Review
Once you've submitted your pull request, the project maintainers will review your changes. We may suggest some changes or improvements. This is a normal part of the process, and your contributions are greatly appreciated!
+45 -11
View File
@@ -1,30 +1,64 @@
# /!\ NOTICE /!\
# Many of the developers DO NOT USE the Dockerfile or image.
# While we do test new changes to Docker configuration, it's
# possible that future changes to the repo might break it.
# When changing this file, please try to make it as resiliant
# to such changes as possible; developers shouldn't need to
# worry about Docker unless the build/run process changes.
# Build stage
FROM node:21-alpine AS build
# Install build dependencies
RUN apk add --no-cache git python3 make g++ \
&& ln -sf /usr/bin/python3 /usr/bin/python
# Set up working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Copy the source files
COPY . .
# Install node modules
RUN npm cache clean --force \
&& npm ci
# Run the build command if necessary
RUN npm run build
# Production stage
FROM node:21-alpine
# Set labels
LABEL repo="https://github.com/HeyPuter/puter"
LABEL license="AGPL-3.0,https://github.com/HeyPuter/puter/blob/master/LICENSE.txt"
LABEL version="v1.2.40-beta"
LABEL version="1.2.46-beta-1"
# Debugging
RUN apk add --no-cache bash # useful for debugging
# Install git (required by Puter to check version)
RUN apk add --no-cache git
# Setup working directory
# Set up working directory
RUN mkdir -p /opt/puter/app
WORKDIR /opt/puter/app
# Add source files
# NOTE: This might change (https://github.com/HeyPuter/puter/discussions/32)
# Copy built artifacts and necessary files from the build stage
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY . .
# Set permissions
RUN chown -R node:node /opt/puter/app
USER node
# Install node modules
RUN npm cache clean --force \
&& npm install
EXPOSE 4100
EXPOSE 4000
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://puter.localhost:4100/test || exit 1
ENV NO_VAR_RUNTUME=1
CMD [ "npm", "start" ]
CMD ["npm", "start"]
+88 -4
View File
@@ -1,6 +1,6 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">The Internet OS! Free, Open-Source, and Self-Hostable!</h3>
<h3 align="center">The Internet OS! Free, Open-Source, and Self-Hostable.</h3>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
@@ -15,6 +15,8 @@
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
·
<a href="https://hackerone.com/puter_h1b">Bug Bounty</a>
</p>
<h3 align="center"><img width="700" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-2.webp"></h3>
@@ -29,11 +31,16 @@ Puter is an advanced, open-source internet operating system designed to be featu
## Getting Started
After reading this section, please proceed to [**Self-Hosting**](#%EF%B8%8F-self-hosting-%EF%B8%8F) and [**Configuration**](#configuration) below.
Read these instructions carefully or you may see errors due to
an invalid setup.
### Local Development
```bash
git clone https://github.com/HeyPuter/puter
cd puter
cp .env.example .env
npm install
npm start
```
@@ -44,17 +51,90 @@ This will launch Puter at http://localhost:4000 (or the next available port).
### Using Docker
**note:** it is **not** necessary to run this within a clone of this repository. For contributors, it is recommended to use the [Local Development](#local-development) instructions.
```bash
git clone https://github.com/HeyPuter/puter
cd puter
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
### Using Docker Compose
**note:** it is **not** necessary to run this within a clone of this repository. For contributors, it is recommended to use the [Local Development](#local-development) instructions.
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
See [Configuration](#configuration) for next steps.
<br/>
## ⚠️ Self-Hosting ⚠️
The self-hosted version of Puter is currently in alpha stage and should not be used in production yet. It is under active development and may contain bugs, other issues. Please exercise caution and use it for testing and evaluation purposes only.
### Self-Hosting Differences
Currently, the self-hosted version of Puter is different in a few ways from [Puter.com](https://puter.com):
- There is no built-in way to install or create other apps (see below)
- Several "core" apps are missing, such as **Code** or **Draw**, because we can't include them in this repository
- Some icons are different
Work is ongoing to improve the **App Center** and make it available on self-hosted.
Until then, it's possible to add other apps by manually editing the database file.
This process is not recommended unless you know what you are doing.
The file will appear after you first launch Puter, and should be found in `puter/data/puter-database.sqlite` for Docker,
or `volatile/runtime/puter-database.sqlite` otherwise.
You will need a database tool that can understand SQLite databases.
<br/>
## Configuration
Running the server will generate a configuration file in one of these locations:
- `config/config.json` when [Using Docker](#using-docker)
- `volatile/config/config.json` in [Local Development](#local-development)
- `/etc/puter/config.json` on a server (or within a Docker container)
### Domain Name
To access Puter on your device, you can simply go to the address printed in
the server console (usually `puter.localhost:4100`).
To access Puter from another device, a domain name must be configured, as well as
an `api` subdomain. For example, `example.local` might be the domain name pointing
to the IP address of the server running puter, and `api.example.com` must point to
this address as well. This domain must be specified in the configuration file
(usually `volatile/config/config.json`) as well.
See [domain configuration](./doc/self-hosters/domains.md) for more information.
### Configure the Port
- You can specify a custom port by setting `http_port` to a desired value
- If you're using a reverse-proxy such as nginx or cloudflare, you should
also set `pub_port` to the public (external) port (usually `443`)
- If you have HTTPS enabled on your reverse-proxy, ensure that
`protocol` in config.json is set accordingly
### Default User
By default, Puter will create a user called `default_user`.
This user will have a randomly generated password, which will be printed
in the development console.
A warning will persist in the dev console until this user's
password is changed. Please login to this user and change the password as
your first step.
<br/>
## License
This repository is licensed under AGPL-3.0; However, our SDK (puter.js) is also available under Apache 2.0, as indicated by the license file in that section (packages/puter-js) of this repository.
<br/>
## FAQ
@@ -88,12 +168,16 @@ Puter interacts directly with the DOM and jQuery provides an elegant yet powerfu
## #DoesItRunPuter
- [Minecraft](https://twitter.com/HeyPuter/status/1771957571496092036) | [video](https://www.youtube.com/watch?v=GIowZUXkg5g)
- [Samsung Watch](https://twitter.com/CharmunkDev/status/1781501714543030554)
- [PlayStation 4](https://twitter.com/HeyPuter/status/1767978053014270059)
- [Skyworth TV](https://twitter.com/ericalexdube/status/1767983049277411564)
- [A Fridge!](https://twitter.com/HeyPuter/status/1778890003797745842)
- [Oculus Quest 2](https://twitter.com/HeyPuter/status/1768664081756754012)
- [Tesla Model 3](https://twitter.com/EricLighthall/status/1781479732997214501)
- [Tesla Model S](https://twitter.com/HeyPuter/status/1767971178864587057)
- [Tesla Model Y](https://twitter.com/HeyPuter/status/1772858333751636310)
- Tesla Model 3
- [Nintendo Switch](https://twitter.com/HeyPuter/status/1780645795240538518)
- [Steam Deck](https://twitter.com/everythingSung/status/1782162352403828793)
<br/>
+2
View File
@@ -0,0 +1,2 @@
### `vscode`
- `es6-string-html`
+72
View File
@@ -0,0 +1,72 @@
# Configuring Domains for Self-Hosted Puter
## Local Network Configuration
### Prerequisite Conditions
Ensure the hosting device has a static IP address to prevent potential connectivity issues due to IP changes. This setup will enable seamless access to Puter and its services across your local network.
### Using Hosts Files
The hosts file is a straightforward way to map domain names to IP addresses on individual devices. It's simple to set up but requires manual changes on each device that needs access to the domains.
#### Windows
1. Open Notepad as an administrator.
2. Open the file located at `C:\Windows\System32\drivers\etc\hosts`.
3. Add lines for your domain and subdomain with the server's IP address, in the
following format:
```
192.168.1.10 puter.local
192.168.1.10 api.puter.local
```
#### For macOS and Linux:
1. Open a terminal.
2. Edit the hosts file with a text editor, e.g., `sudo nano /etc/hosts`.
3. Add lines for your domain and subdomain with the server's IP address, in the
following format:
```
192.168.1.10 puter.local
192.168.1.10 api.puter.local
```
4. Save and exit the editor.
### Using Router Configuration
Some routers allow you to add custom DNS rules, letting you configure domain names network-wide without touching each device.
1. Access your router’s admin interface (usually through a web browser).
2. Look for DNS or DHCP settings.
3. Add custom DNS mappings for `puter.local` and `api.puter.local` to the hosting device's IP address.
4. Save the changes and reboot the router if necessary.
This method's availability and steps may vary depending on your router's model and firmware.
### Using Local DNS
Setting up a local DNS server on your network allows for flexible and scalable domain name resolution. This method works across all devices automatically once they're configured to use the DNS server.
#### Options for DNS Software:
- **Pi-hole**: Acts as both an ad-blocker and a DNS server. Ideal for easy setup and maintenance.
- **BIND9**: Offers comprehensive DNS server capabilities for complex setups.
- **dnsmasq**: Lightweight and suitable for smaller networks or those new to running a DNS server.
**contributors note:** feel free to add any software you're aware of
which might help with this to the list. Also, feel free to add instructions here for specific software; our goal is for Puter to be easy to setup with tools you're already familiar with.
#### General Steps:
1. Choose and install DNS server software on a device within your network.
2. Configure the DNS server to resolve `puter.local` and `api.puter.local` to the IP address of your Puter hosting device.
3. Update your router's DHCP settings to distribute the DNS server's IP address to all devices on the network.
By setting up a local DNS server, you gain the most flexibility and control over your network's domain name resolution, ensuring that all devices can access Puter and its API without manual configuration.
## Production Configuration
Please note the self-hosting feature is still in alpha and a public production
deployment is not recommended at this time. However, if you wish to host
publicly you can do so following the same steps you normally would to configure
a domain name and ensuring the `api` subdomain points to the server as well.
+39
View File
@@ -0,0 +1,39 @@
## Puter Support Levels for Repository Updates
This document describes issues requiring repository changes;
which issues will be fixed by Puter's core team, and which ones
will be fixed if the community makes a contribution.
This document is not "law". It is provided only as a helpful guide
on what to expect.
### Level Glossary
| Name | Description |
| ---- | ----------- |
| Core | Core developers will fix this |
| Community | We will accept contributions to fix this |
| Mixed | Core developers will fix this if it's currently a priority |
### Issues and their Levels
| Issue | Priority |
| ----- | -------- |
| Security vulnerability | Core |
| Breaking change to SDK or API | Core |
| Bug in service in CoreModule | Core |
| Bug in a built-in app | Core |
| Login/init failure in Docker on `release` branch | Core |
| Login/init failure in Linux or OSX | Core |
| Login/init failure in Docker on `main` branch | Mixed |
| Login/init failure with specific configuration | Mixed |
| Login/init failure in Windows | Community |
## Puter Support for a Particular Deployment
If you experience issues on a self-hosted deployment we're here to
help. Some issues are related to configuration or environment, so
we may only be able to help in a limited capacity. Issues related
to data loss, data corruption, or security will have higher priority
over other issues with particular deployments.
+23 -5
View File
@@ -1,7 +1,25 @@
version: '3'
---
version: "3.8"
services:
app:
build: ./
puter:
container_name: puter
image: ghcr.io/heyputer/puter:latest
pull_policy: always
# build: ./
restart: unless-stopped
ports:
- 4000:4000
- '4100:4100'
environment:
# TZ: Europe/Paris
# CONFIG_PATH: /etc/puter
PUID: 1000
PGID: 1000
volumes:
- ./puter/config:/etc/puter
- ./puter/data:/var/puter
healthcheck:
test: wget --no-verbose --tries=1 --spider http://puter.localhost:4100/test || exit 1
interval: 30s
timeout: 3s
retries: 3
start_period: 30s
+106
View File
@@ -0,0 +1,106 @@
import js from "@eslint/js";
import globals from "globals";
export default [
js.configs.recommended,
{
// Global ignores
ignores: [
"**/*.min.js",
"**/src/lib/**",
"**/dist/",
"packages/backend/src/public/assets/**",
],
},
{
// Top-level and tools use Node
files: [
"tools/**/*.js",
],
languageOptions: {
globals: {
...globals.node,
}
}
},
{
// Back end
files: [
"packages/backend/**/*.js",
"dev-server.js",
"utils.js",
],
languageOptions: {
globals: {
...globals.node,
"kv": true,
}
}
},
{
// Front end
files: [
"index.js",
"initgui.js",
"src/**/*.js",
"packages/**/*.js",
],
ignores: [
"packages/backend/**/*.js",
],
languageOptions: {
globals: {
...globals.browser,
...globals.commonjs,
"puter": true,
"i18n": true,
"html_encode": true,
"html_decode": true,
"isMobile": true,
// Libraries
"saveAs": true, // FileSaver
"iro": true, // iro.js color picker
"$": true, // jQuery
"jQuery": true, // jQuery
"JSZip": true, // JSZip
"_": true, // lodash
"QRCode": true, // qrcode
"io": true, // socket.io
"timeago": true, // timeago
"SelectionArea": true, // viselect
}
}
},
{
// Tests
files: [
"**/test/**/*.js",
],
languageOptions: {
globals: {
...globals.mocha,
}
}
},
{
// Phoenix
files: [
"packages/phoenix/**/*.js",
],
languageOptions: {
globals: {
...globals.node,
}
}
},
{
// Global rule settings
rules: {
"no-prototype-builtins": "off", // Complains about any use of hasOwnProperty()
"no-unused-vars": "off", // Temporary, we just have a lot of these
"no-debugger": "warn",
"no-async-promise-executor": "off", // We do this quite often and it's fine
}
},
];
+2928 -1073
View File
File diff suppressed because it is too large. Load diff
+7 -3
View File
@@ -1,6 +1,6 @@
{
"name": "puter.com",
"version": "1.0.0",
"version": "2.3.0",
"author": "Puter Technologies Inc.",
"license": "AGPL-3.0-only",
"description": "Desktop environment in the browser!",
@@ -11,10 +11,13 @@
"lib": "lib"
},
"devDependencies": {
"@eslint/js": "^9.1.1",
"chalk": "^4.1.0",
"clean-css": "^5.3.2",
"dotenv": "^16.4.5",
"eslint": "^9.1.1",
"express": "^4.18.2",
"globals": "^15.0.0",
"html-entities": "^2.3.3",
"nodemon": "^3.1.0",
"uglify-js": "^3.17.4",
@@ -22,11 +25,12 @@
"webpack-cli": "^5.1.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "mocha ./packages/phoenix/test ./packages/phoenix/packages/contextlink/test",
"start=gui": "nodemon --exec \"node dev-server.js\" ",
"start": "node run-selfhosted.js",
"build": "node ./build.js",
"check-translations": "node tools/check-translations.js"
"check-translations": "node tools/check-translations.js",
"postinstall": "cd packages/phoenix && cd packages/contextlink && npm install && cd - && cd packages/strataparse && npm install && cd - && cd packages/pty && npm install"
},
"workspaces": [
"packages/*"
@@ -0,0 +1,87 @@
# Puter Backend Boot Sequence
This document describes the boot sequence of Puter's backend.
**Constriction**
- Data structures are created
**Initialization**
- Registries are populated
- Services prepare for next phase
**Consolidation**
- Service event bus receives first event (`boot.consolidation`)
- Services perform coordinated setup behaviors
- Services prepare for next phase
**Activation**
- Blocking listeners of `boot.consolidation` have resolved
- HTTP servers start listening
**Ready**
- Services are informed that Puter is providing service
## Boot Phases
### Construction
Services implement a method called `construct` which initializes members
of an instance. Services do not override the class constructor of
**BaseService**. This makes it possible to use the `new` operator without
invoking a service's constructor behavior during debugging.
The first phase of the boot sequence, "construction", is simply a loop to
call `construct` on all registered services.
The `_construct` override should not:
- call other services
- emit events
### Initialization
At initialization, the `init()` method is called on all services.
The `_init` override can be used to:
- register information with other services, when services don't
need to register this information in a specific sequence.
An example of this is registering commands with CommandService.
- perform setup that is required before the consolidation phase starts.
### Consolidation
Consolidation is a phase where services should emit events that
are related to bringing up the system. For example, WebServerService
('web-server') emits an event telling services to install middlewares,
and later emits an event telling services to install routes.
Consolidation starts when Kernel emits `boot.consolidation` to the
services event bus, which happens after `init()` resolves for all
services.
### Activation
Activation is a phase where services begin listening on external
interfaces. For example, this is when the web server starts listening.
Activation starts when Kernel emits `boot.activation`.
### Ready
Ready is a phase where services are informed that everything is up.
Ready starts when Kernel emits `boot.ready`.
## Events and Asynchronous Execution
The services event bus is implemented so you can `await` a call to `.emit()`.
Event listeners can choose to have blocking behavior by returning a promise.
During emission of a particular event, listeners of this event will not
block each other, but all listeners must resolve before the call to
`.emit()` is resolved. (i.e. `emit` uses `Promise.all`)
## Legacy Services
Some services were implemented before the `BaseService` class - which
implements the `init` method - was created. These services are called
"legacy services" and they are instantiated _after_ initialization but
_before_ consolidation.
+2 -2
View File
@@ -55,8 +55,8 @@ If your answer is the second, you should find a way to
In my experience, the harder I think about the correct way to implement
something, the bigger a mistake I'm going to make; ***unless*** a big part
of the reason I'm thinking so hard is because I want to find a solution
that reduces complexity and has the right maintanence trade-off.
that reduces complexity and has the right maintenance trade-off.
There's no easy solution for this so just keep it in mind; there are some
things we might write 2 times, 3 times, even more times over before we
really get it right and *that's okay*; sometimes part of doing useful work is
doing the useless work that reveals what the useful work is.
doing the useless work that reveals what the useful work is.
+3 -1
View File
@@ -18,8 +18,9 @@
*/
const CoreModule = require("./src/CoreModule.js");
const { Kernel } = require("./src/Kernel.js");
const LocalDiskStorageModule = require("./src/LocalDiskStorageModule.js");
const DatabaseModule = require("./src/DatabaseModule.js");
const LocalDiskStorageModule = require("./src/LocalDiskStorageModule.js");
const SelfHostedModule = require("./src/SelfHostedModule.js");
const PuterDriversModule = require("./src/PuterDriversModule.js");
const { testlaunch } = require("./src/index.js");
const BaseService = require("./src/services/BaseService.js");
@@ -44,4 +45,5 @@ module.exports = {
DatabaseModule,
PuterDriversModule,
LocalDiskStorageModule,
SelfHostedModule,
};
+5 -4
View File
@@ -1,17 +1,15 @@
{
"name": "@heyputer/backend",
"version": "1.0.0",
"version": "2.1.0",
"description": "Backend/Kernel for Puter",
"main": "exports.js",
"scripts": {
"test": "npx mocha"
},
"workspaces": [
"packages/*"
],
"dependencies": {
"@heyputer/kv.js": "^0.1.3",
"@heyputer/multest": "^0.0.2",
"@heyputer/puter-js-common": "^1.0.0",
"@opentelemetry/api": "^1.4.1",
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.40.0",
@@ -30,11 +28,13 @@
"composite-error": "^1.0.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"dedent": "^1.5.3",
"express": "^4.18.2",
"file-type": "^18.5.0",
"form-data": "^4.0.0",
"handlebars": "^4.7.8",
"helmet": "^7.0.0",
"hi-base32": "^0.5.1",
"html-entities": "^2.3.3",
"is-glob": "^4.0.3",
"isbot": "^3.7.1",
@@ -54,6 +54,7 @@
"nodemailer": "^6.9.3",
"on-finished": "^2.4.1",
"openai": "^4.20.1",
"otpauth": "9.2.4",
"prompt-sync": "^4.2.0",
"recursive-readdir": "^2.2.3",
"response-time": "^2.3.2",
@@ -1,7 +1,7 @@
# Puter - Common Javascript Module
This is a small module for javascript which you might call a
"langauge tool"; it adds some behavior to make javascript classes
"language tool"; it adds some behavior to make javascript classes
more flexible, with an aim to avoid any significant complexity.
Each class in this module is best described as an _idea_:
@@ -9,7 +9,7 @@ Each class in this module is best described as an _idea_:
### BasicBase
**BasicBase** is the idea that there should be a common way to
see the inheretence chain of the current instance, and obtain
see the inheritance chain of the current instance, and obtain
merged objects and arrays from static members of these classes.
### TraitBase
@@ -1,5 +1,5 @@
{
"name": "puter-js-common",
"name": "@heyputer/puter-js-common",
"version": "1.0.0",
"description": "",
"main": "index.js",
+31 -7
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { Context } = require('./util/context');
@@ -43,6 +43,11 @@ module.exports = CoreModule;
const install = async ({ services, app }) => {
const config = require('./config');
// /!\ IMPORTANT /!\
// For new services, put the import immediate above the
// call to services.registerService. We'll clean this up
// in a future PR.
const { LogService } = require('./services/runtime-analysis/LogService');
const { PagerService } = require('./services/runtime-analysis/PagerService');
const { AlarmService } = require('./services/runtime-analysis/AlarmService');
@@ -182,9 +187,32 @@ const install = async ({ services, app }) => {
const { EventService } = require('./services/EventService');
services.registerService('event', EventService);
const DefaultUserService = require('./services/DefaultUserService');
services.registerService('__default-user', DefaultUserService);
const { PuterVersionService } = require('./services/PuterVersionService');
services.registerService('puter-version', PuterVersionService);
const { SessionService } = require('./services/SessionService');
services.registerService('session', SessionService);
const { EdgeRateLimitService } = require('./services/abuse-prevention/EdgeRateLimitService');
services.registerService('edge-rate-limit', EdgeRateLimitService);
const { Emailservice } = require('./services/EmailService');
services.registerService('email', Emailservice);
const { TokenService } = require('./services/auth/TokenService');
services.registerService('token', TokenService);
const { OTPService } = require('./services/auth/OTPService');
services.registerService('otp', OTPService);
const { UserProtectedEndpointsService } = require("./services/web/UserProtectedEndpointsService");
services.registerService('__user-protected-endpoints', UserProtectedEndpointsService);
const { AntiCSRFService } = require('./services/auth/AntiCSRFService');
services.registerService('anti-csrf', AntiCSRFService);
const { LockService } = require('./services/LockService');
services.registerService('lock', LockService);
}
const install_legacy = async ({ services }) => {
@@ -195,9 +223,7 @@ const install_legacy = async ({ services }) => {
const PerformanceMonitor = require('./monitor/PerformanceMonitor');
const { OperationTraceService } = require('./services/OperationTraceService');
const { WSPushService } = require('./services/WSPushService');
const { PuterVersionService } = require('./services/PuterVersionService');
const { ReferralCodeService } = require('./services/ReferralCodeService');
const { Emailservice } = require('./services/EmailService');
const { ClientOperationService } = require('./services/ClientOperationService');
const { EngPortalService } = require('./services/EngPortalService');
const { AppInformationService } = require('./services/AppInformationService');
@@ -210,9 +236,7 @@ const install_legacy = async ({ services }) => {
services.registerService('filesystem', FilesystemService);
services.registerService('operationTrace', OperationTraceService);
services.registerService('__event-push-ws', WSPushService);
services.registerService('puter-version', PuterVersionService);
services.registerService('referral-code', ReferralCodeService);
services.registerService('email', Emailservice);
services.registerService('file-cache', FileCacheService);
services.registerService('client-operation', ClientOperationService);
services.registerService('app-information', AppInformationService);
+1 -1
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
class DatabaseModule extends AdvancedBase {
async install (context) {
+5 -19
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { Context } = require('./util/context');
class Kernel extends AdvancedBase {
@@ -95,11 +95,8 @@ class Kernel extends AdvancedBase {
root_context.arun(async () => {
await this._install_modules();
});
(async () => {
await this._boot_services();
})();
});
// Error.stackTraceLimit = Infinity;
@@ -155,17 +152,7 @@ class Kernel extends AdvancedBase {
const { services } = this;
await services.ready;
{
const app = services.get('web-server').app;
app.use(async (req, res, next) => {
req.services = services;
next();
});
await services.emit('boot.services-initialized');
await services.emit('install.middlewares.context-aware', { app });
await services.emit('install.routes', { app });
await services.emit('install.routes-gui', { app });
}
await services.emit('boot.consolidation');
// === END: Initialize Service Registry ===
@@ -181,9 +168,8 @@ class Kernel extends AdvancedBase {
});
})();
await services.emit('start.webserver');
await services.emit('ready.webserver');
await services.emit('boot.activation');
await services.emit('boot.ready');
}
}
@@ -16,13 +16,16 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
class LocalDiskStorageModule extends AdvancedBase {
async install (context) {
const services = context.get('services');
const LocalDiskStorageService = require("./services/LocalDiskStorageService");
services.registerService('local-disk-storage', LocalDiskStorageService);
const HostDiskUsageService = require('./services/HostDiskUsageService');
services.registerService('host-disk-usage', HostDiskUsageService);
}
}
+1 -1
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
class PuterDriversModule extends AdvancedBase {
async install () {}
+66
View File
@@ -0,0 +1,66 @@
const { AdvancedBase } = require("@heyputer/puter-js-common");
const config = require("./config");
class SelfHostedModule extends AdvancedBase {
async install (context) {
const services = context.get('services');
const DefaultUserService = require('./services/DefaultUserService');
services.registerService('__default-user', DefaultUserService);
const ComplainAboutVersionsService = require('./services/ComplainAboutVersionsService');
services.registerService('complain-about-versions', ComplainAboutVersionsService);
const DevWatcherService = require('./services/DevWatcherService');
const path_ = require('path');
services.registerService('__dev-watcher', DevWatcherService, {
root: path_.resolve(__dirname, '../../../'),
commands: [
{
name: 'puter.js:webpack-watch',
directory: 'packages/puter-js',
command: 'npm',
args: ['run', 'start-webpack'],
},
{
name: 'terminal:rollup-watch',
directory: 'packages/terminal',
command: 'npx',
args: ['rollup', '-c', 'rollup.config.js', '--watch'],
env: {
PUTER_JS_URL: ({ global_config: config }) => config.origin + '/sdk/puter.dev.js',
}
},
{
name: 'phoenix:rollup-watch',
directory: 'packages/phoenix',
command: 'npx',
args: ['rollup', '-c', 'rollup.config.js', '--watch'],
env: {
PUTER_JS_URL: ({ global_config: config }) => config.origin + '/sdk/puter.dev.js',
}
},
],
});
const ServeStaticFilesService = require("./services/ServceStaticFilesService");
services.registerService('__serve-puterjs', ServeStaticFilesService, {
directories: [
{
prefix: '/sdk',
path: path_.resolve(__dirname, '../../../packages/puter-js/dist'),
},
{
prefix: '/builtin/terminal',
path: path_.resolve(__dirname, '../../../packages/terminal/dist'),
},
{
prefix: '/builtin/phoenix',
path: path_.resolve(__dirname, '../../../packages/phoenix/dist'),
},
],
});
}
}
module.exports = SelfHostedModule;
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
class ThirdPartyDriversModule extends AdvancedBase {
// constructor () {
+46
View File
@@ -128,6 +128,10 @@ module.exports = class APIError {
return `Invalid id`;
}
},
'invalid_operation': {
status: 400,
message: ({ operation }) => `Invalid operation: ${quot(operation)}.`,
},
'field_invalid': {
status: 400,
message: ({ key, expected, got }) => {
@@ -216,6 +220,10 @@ module.exports = class APIError {
status: 400,
message: 'Missing fileinfo entry or BLOB for operation.',
},
'invalid_file_metadata': {
status: 400,
message: 'Invalid file metadata.',
},
// Open
'no_suitable_app': {
@@ -315,6 +323,10 @@ module.exports = class APIError {
status: 401,
message: 'This authentication token is not supported here.',
},
'token_expired': {
status: 401,
message: 'Authentication token has expired.',
},
'account_suspended': {
status: 403,
message: 'Account suspended.',
@@ -327,6 +339,40 @@ module.exports = class APIError {
status: 403,
message: 'Attempted to create an access token with no permissions.',
},
'invalid_action': {
status: 400,
message: ({ action }) => `Invalid action: ${quot(action)}.`,
},
'2fa_already_enabled': {
status: 409,
message: '2FA is already enabled.',
},
'2fa_not_configured': {
status: 409,
message: '2FA is not configured.',
},
// protected endpoints
'too_many_requests': {
status: 429,
message: 'Too many requests.',
},
'user_tokens_only': {
status: 403,
message: 'This endpoint must be requested with a user session',
},
'temporary_accounts_not_allowed': {
status: 403,
message: 'Temporary accounts cannot perform this action',
},
'password_required': {
status: 400,
message: 'Password is required.',
},
'password_mismatch': {
status: 403,
message: 'Password does not match.',
},
// Object Mapping
'field_not_allowed_for_create': {
@@ -16,6 +16,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const APIError = require('../../api/APIError');
module.exports = class FlagParam {
constructor (srckey, options) {
this.srckey = srckey;
@@ -16,6 +16,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const APIError = require('../../api/APIError');
module.exports = class StringParam {
constructor (srckey, options) {
this.srckey = srckey;
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { quot } = require("../util/strutil");
const { TechnicalError } = require("../errors/TechnicalError");
const { print_error_help } = require("../errors/error_help_details");
+1 -1
View File
@@ -109,7 +109,7 @@ class Sequence {
async run (values) {
// Initialize scope
values = values || this.thisArg?.values || {};
Object.assign(this.scope_, values);
Object.assign(this.scope_, values); // TODO: can this be __proto__?
// Run sequence
for ( ; this.i < this.steps.length ; this.i++ ) {
+14 -1
View File
@@ -53,10 +53,17 @@ config.max_subdomains_per_user = 2000;
config.storage_capacity = 1*1024*1024*1024;
config.static_hosting_domain = '-static.puter.local';
// Storage limiting is set to false by default
// Storage available on the mountpoint/drive puter is running is the storage available
config.is_storage_limited = false;
config.available_device_storage = null;
config.thumb_width = 80;
config.thumb_height = 80;
config.app_max_icon_size = 5*1024*1024;
config.defaultjs_asset_path = '../../';
// config.origin = config.protocol + '://' + config.domain;
// config.api_base_url = config.protocol + '://api.' + config.domain;
// config.social_card = `${config.origin}/assets/img/screenshot.png`;
@@ -92,6 +99,10 @@ if (config.server_id) {
config.contact_email = 'hey@' + config.domain;
// TODO: default value will be changed to false in a future release;
// details to follow in a future announcement.
config.legacy_token_migrate = true;
module.exports = config;
// NEW_CONFIG_LOADING
@@ -100,7 +111,9 @@ const computed_defaults = {
pub_port: config => config.http_port,
origin: config => config.protocol + '://' + config.domain +
(config.pub_port !== 80 && config.pub_port !== 443 ? ':' + config.pub_port : ''),
api_base_url: config => config.protocol + '://api.' + config.domain +
api_base_url: config => config.experimental_no_subdomain
? config.origin
: config.protocol + '://api.' + config.domain +
(config.pub_port !== 80 && config.pub_port !== 443 ? ':' + config.pub_port : ''),
social_card: config => `${config.origin}/assets/img/screenshot.png`,
};
+1 -1
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { quot } = require("../util/strutil");
class ConfigLoader extends AdvancedBase {
@@ -387,21 +387,9 @@ module.exports = class FSNodeContext {
* @deprecated sharing will use user-to-user permissions
*/
async fetchShares (force) {
if ( this.entry.permissions && ! force ) return;
const db = this.services.get('database').get(DB_READ, 'filesystem');
let shares = await db.read(
`SELECT share.id as share_id, user.* FROM share
INNER JOIN user ON share.recipient_user_id = user.id
WHERE share.fsentry_id = ?`,
[this.entry.id]
);
const shares_tidy = [];
for ( const share of shares ) {
shares_tidy.push({uid: share.share_id, username: share.username, email: share.email});
}
this.entry.permissions = shares_tidy;
// NOOP: this was for legacy sharing functionality;
// this is being re-implemented with permissions
return;
}
/**
@@ -27,15 +27,17 @@ const SystemFSEntryService = require('./storage/SystemFSEntryService.js');
const PerformanceMonitor = require('../monitor/PerformanceMonitor.js');
const { NodePathSelector, NodeUIDSelector, NodeInternalIDSelector } = require('./node/selectors.js');
const FSNodeContext = require('./FSNodeContext.js');
const { AdvancedBase } = require('puter-js-common');
const { AdvancedBase } = require('@heyputer/puter-js-common');
const { Context } = require('../util/context.js');
const { simple_retry } = require('../util/retryutil.js');
const APIError = require('../api/APIError.js');
const { LLMkdir } = require('./ll_operations/ll_mkdir.js');
const { LLCWrite, LLOWrite } = require('./ll_operations/ll_write.js');
const { LLCopy } = require('./ll_operations/ll_copy.js');
const { PermissionUtil, PermissionRewriter } = require('../services/auth/PermissionService.js');
const { PermissionUtil, PermissionRewriter, PermissionImplicator } = require('../services/auth/PermissionService.js');
const { DB_WRITE } = require("../services/database/consts");
const { UserActorType } = require('../services/auth/Actor');
const { get_user } = require('../helpers');
class FilesystemService extends AdvancedBase {
static MODULES = {
@@ -131,6 +133,38 @@ class FilesystemService extends AdvancedBase {
return `fs:${uid}:${rest.join(':')}`;
},
}));
svc_permission.register_implicator(PermissionImplicator.create({
matcher: permission => {
return permission.startsWith('fs:');
},
checker: async (actor, permission) => {
if ( !(actor.type instanceof UserActorType) ) {
return undefined;
}
const [_, uid] = PermissionUtil.split(permission);
const node = await this.node(new NodeUIDSelector(uid));
if ( ! await node.exists() ) {
return undefined;
}
const owner_id = await node.get('user_id');
// These conditions should never happen
if ( ! owner_id || ! actor.type.user.id ) {
throw new Error(
'something unexpected happened'
);
}
if ( owner_id === actor.type.user.id ) {
return {};
}
return undefined;
},
}));
}
/**
@@ -328,7 +362,7 @@ class FilesystemService extends AdvancedBase {
[new_path, old_path.length + 1, old_path + '%', user_id]
);
const log = services.get('log-service').create('update_child_paths');
const log = this.services.get('log-service').create('update_child_paths');
log.info(`updated ${old_path} -> ${new_path}`);
monitor.end();
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require('puter-js-common');
const { AdvancedBase } = require('@heyputer/puter-js-common');
const PathResolver = require('../../routers/filesystem_api/batch/PathResolver');
const commands = require('./commands').commands;
const { WorkUnit } = require('../../services/runtime-analysis/ExpectationService');
@@ -85,6 +85,12 @@ class BatchExecutor extends AdvancedBase {
if ( ! x ) throw new Error('no context');
try {
if ( ! command_cls ) {
throw APIError.create('invalid_operation', null, {
operation: op.op,
});
}
if ( file ) workUnit.checkpoint(
'about to run << ' +
(file.originalname ?? file.name) +
@@ -112,7 +118,7 @@ class BatchExecutor extends AdvancedBase {
alarm: true,
});
e = APIError.adapt(e);
e = APIError.adapt(e); // eslint-disable-line no-ex-assign
}
// Consume stream if there's a file
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { AsyncProviderTrait } = require("../../traits/AsyncProviderTrait");
const { HLMkdir, QuickMkdir } = require("../hl_operations/hl_mkdir");
const { Context } = require("../../util/context");
@@ -23,6 +23,7 @@ const { NodePathSelector, RootNodeSelector } = require("../node/selectors");
const { HLFilesystemOperation } = require("./definitions");
const { MkTree } = require("./hl_mkdir");
const { HLRemove } = require("./hl_remove");
const config = require("../../config");
class HLCopy extends HLFilesystemOperation {
static DESCRIPTION = `
@@ -141,7 +142,7 @@ class HLCopy extends HLFilesystemOperation {
let deset_usage = await sizeService.get_usage(dest_user.id);
const size = await source.fetchSize(values.user);
let capacity = (dest_user.free_storage === undefined || dest_user.free_storage === null) ? config.storage_capacity : dest_user.free_storage
let capacity = config.is_storage_limited ? (dest_user.free_storage === undefined || dest_user.free_storage === null) ? config.storage_capacity : dest_user.free_storage : config.available_device_storage
if(capacity - deset_usage - size < 0){
throw APIError.create('storage_limit_reached');
}
@@ -162,6 +163,7 @@ class HLCopy extends HLFilesystemOperation {
throw APIError('cannot_copy_item_into_itself');
}
let overwritten;
if ( await dest.exists() ) {
// condition: no overwrite behaviour specified
if ( ! values.overwrite && ! values.dedupe_name ) {
@@ -188,12 +190,13 @@ class HLCopy extends HLFilesystemOperation {
dest = await parent.getChild(target_name);
}
else if ( values.overwrite ) {
if ( ! await chkperm(dest.entry, options.user.id, 'rm') ) {
if ( ! await chkperm(dest.entry, values.user.id, 'rm') ) {
throw APIError.create('forbidden');
}
// TODO: This will be LLRemove
// TODO: what to do with parent_operation?
overwritten = await dest.getSafeEntry();
const hl_remove = new HLRemove();
await hl_remove.run({
target: dest,
@@ -212,7 +215,10 @@ class HLCopy extends HLFilesystemOperation {
await this.copied.awaitStableEntry();
const response = await this.copied.getSafeEntry({ thumbnail: true });
return response;
return {
copied : response,
overwritten
};
}
}
@@ -18,6 +18,9 @@
*/
const { stream_to_buffer } = require("../../util/streamutil");
const { HLFilesystemOperation } = require("./definitions");
const { chkperm } = require('../../helpers');
const { LLRead } = require('../ll_operations/ll_read');
const APIError = require('../../api/APIError');
/**
* HLDataRead reads a stream of objects from a file containing structured data.
@@ -38,6 +41,7 @@ class HLDataRead extends HLFilesystemOperation {
const {
fsNode,
version_id,
} = this.values;
if ( ! await fsNode.exists() ) {
@@ -85,6 +89,7 @@ class HLDataRead extends HLFilesystemOperation {
}
_stream_jsonl_lines_to_objects (stream) {
const { PassThrough } = this.modules.stream;
const output_stream = new PassThrough();
(async () => {
for await (const line of stream) {
@@ -63,6 +63,7 @@ class MkTree extends HLFilesystemOperation {
async _run () {
const { values, context } = this;
const fs = context.get('services').get('filesystem');
await this.create_branch_({
parent_node: values.parent || await fs.node(new RootNodeSelector()),
@@ -17,13 +17,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const APIError = require("../../api/APIError");
const { chkperm, validate_fsentry_name, is_ancestor_of } = require("../../helpers");
const { chkperm, validate_fsentry_name, is_ancestor_of, df, get_user } = require("../../helpers");
const { LLMove } = require("../ll_operations/ll_move");
const { RootNodeSelector } = require("../node/selectors");
const { HLFilesystemOperation } = require("./definitions");
const { MkTree } = require("./hl_mkdir");
const { HLRemove } = require("./hl_remove");
const { TYPE_DIRECTORY } = require("../FSNodeContext");
const config = require("../../config");
class HLMove extends HLFilesystemOperation {
static MODULES = {
@@ -105,7 +106,7 @@ class HLMove extends HLFilesystemOperation {
dest_user = source_user;
await source.fetchSize();
const item_size = source.entry.size;
let capacity = (dest_user.free_storage === undefined || dest_user.free_storage === null) ? config.storage_capacity : dest_user.free_storage
let capacity = config.is_storage_limited ? (dest_user.free_storage === undefined || dest_user.free_storage === null) ? config.storage_capacity : dest_user.free_storage : config.available_device_storage;
if(capacity - await df(dest_user.id) - item_size < 0){
throw APIError.create('storage_limit_reached');
}
@@ -41,7 +41,7 @@ class HLRead extends HLFilesystemOperation {
}
const ll_read = new LLRead();
const stream = await ll_read.run({
let stream = await ll_read.run({
fsNode, actor,
version_id,
...(byte_count !== undefined ? {
@@ -24,7 +24,7 @@ const { HLFilesystemOperation } = require("./definitions");
class HLReadDir extends HLFilesystemOperation {
async _run () {
const { subject, user, no_thumbs, no_assocs } = this.values;
const { subject, user, no_thumbs, no_assocs, actor } = this.values;
if ( ! await subject.exists() ) {
throw APIError.create('subject_does_not_exist');
@@ -49,12 +49,12 @@ class HLReadDir extends HLFilesystemOperation {
await child.fetchSubdomains(user);
}
const fs = require('fs');
fs.appendFileSync('/tmp/children.log',
JSON.stringify({
no_thumbs,
no_assocs,
entry: child.entry,
}) + '\n');
// fs.appendFileSync('/tmp/children.log',
// JSON.stringify({
// no_thumbs,
// no_assocs,
// entry: child.entry,
// }) + '\n');
return await child.getSafeEntry({ thumbnail: ! no_thumbs });
}));
}
@@ -19,6 +19,7 @@
const { chkperm } = require("../../helpers");
const { Context } = require("../../util/context");
const { HLFilesystemOperation } = require("./definitions");
const APIError = require('../../api/APIError');
class HLStat extends HLFilesystemOperation {
static MODULES = {
@@ -45,7 +46,7 @@ class HLStat extends HLFilesystemOperation {
const svc_acl = context.get('services').get('acl');
const actor = context.get('actor');
if ( ! await svc_acl.check(actor, subject, 'read') ) {
throw await svc_acl.get_safe_acl_error(actor, subject.entry, 'read');
throw await svc_acl.get_safe_acl_error(actor, subject, 'read');
}
// check permission
@@ -61,8 +61,8 @@ class WriteCommonTrait {
const { file, user } = this.values;
const usage = await sizeService.get_usage(user.id);
let capacity = user.free_storage == undefined
? config.storage_capacity : user.free_storage;
let capacity = config.is_storage_limited ? user.free_storage == undefined
? config.storage_capacity : user.free_storage : config.available_device_storage;
if( capacity - usage - file.size < 0 ) {
throw APIError.create('storage_limit_reached');
}
@@ -64,10 +64,6 @@ class PuterPath {
return ! this.isAbsolute();
}
get hasRelativePortion () {
}
get reference () {
if ( this.isAbsolute ) return this.constructor.NULL_UUID;
@@ -30,6 +30,7 @@
- easier to diagnose stuck operations
*/
/* eslint-disable */
const STEPS_COPY_CONTENTS = [
{
@@ -91,7 +91,7 @@ class LLRead extends LLFilesystemOperation {
const context = a.iget('context');
const svc_fileCache = context.get('services').get('file-cache');
const { fsNode } = a.values();
const { fsNode, offset, length } = a.values();
const maybe_buffer = await svc_fileCache.try_get(fsNode, a.log);
if ( maybe_buffer ) {
@@ -17,9 +17,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const APIError = require("../../api/APIError");
const { chkperm, get_descendants } = require("../../helpers");
const { TYPE_DIRECTORY } = require("../FSNodeContext");
const { NodeUIDSelector, NodeRawEntrySelector } = require("../node/selectors");
const { RootNodeSelector } = require("../node/selectors");
const { NodeUIDSelector, NodeChildSelector } = require("../node/selectors");
const { LLFilesystemOperation } = require("./definitions");
class LLReadDir extends LLFilesystemOperation {
@@ -42,27 +41,14 @@ class LLReadDir extends LLFilesystemOperation {
const svc_fsentry = svc.get('fsEntryService');
const svc_fs = svc.get('filesystem');
if (
subject.isRoot ||
(await subject.isUserDirectory() && subject.name !== user.username)
) {
this.checkpoint('before call to get_descendants')
const entries = await get_descendants(
await subject.get('path'),
user,
1, true,
)
this.checkpoint('after call to get_descendants')
const children = await Promise.all(entries.map(async entry => {
const node = await svc_fs.node(new NodeRawEntrySelector(entry));
node.found_thumbnail = false;
return node;
}))
this.checkpoint('after get children (2)');
return children;
if ( subject.isRoot ) {
if ( ! actor.type.user ) return [];
return [
await svc_fs.node(new NodeChildSelector(
new RootNodeSelector(),
actor.type.user.username,
))
];
}
this.checkpoint('before get direct descendants')
@@ -19,6 +19,7 @@
const { Context } = require("../../util/context");
const { ParallelTasks } = require("../../util/otelutil");
const { LLFilesystemOperation } = require("./definitions");
const APIError = require("../../api/APIError");
class LLRmNode extends LLFilesystemOperation {
async _run () {
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { id2path } = require("../../helpers");
const { PuterPath } = require("../lib/PuterPath");
@@ -17,6 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { PuterPath } = require("../lib/PuterPath");
const _path = require('path');
// Redis keys:
// <env>:<service>:<class>:<type>:<property>:<id>
@@ -22,10 +22,12 @@ This module contains functions that validate filesystem operations.
*/
/* eslint-disable no-control-regex */
const config = require("../config");
const path_excludes = () => /[\x00-\x1F]/g;
const node_excludes = () => /[\/\x00-\x1F]/g;
const node_excludes = () => /[/\x00-\x1F]/g;
// this characters are not allowed in path names because
// they might be used to trick the user into thinking
+47 -88
View File
@@ -184,7 +184,7 @@ async function id2uuid(id){
const cached = options.cached ?? true;
if ( cached ) {
if ( cached && ! options.force ) {
if (options.username) user = kv.get('users:username:' + options.username);
else if (options.email) user = kv.get('users:email:' + options.email);
else if (options.uuid) user = kv.get('users:uuid:' + options.uuid);
@@ -194,16 +194,18 @@ async function id2uuid(id){
if ( user ) return user;
}
if(options.username)
user = await db.read("SELECT * FROM `user` WHERE `username` = ? LIMIT 1", [options.username]);
else if(options.email)
user = await db.read("SELECT * FROM `user` WHERE `email` = ? LIMIT 1", [options.email]);
else if(options.uuid)
user = await db.read("SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1", [options.uuid]);
else if(options.id)
user = await db.read("SELECT * FROM `user` WHERE `id` = ? LIMIT 1", [options.id]);
else if(options.referral_code)
user = await db.read("SELECT * FROM `user` WHERE `referral_code` = ? LIMIT 1", [options.referral_code]);
if ( ! options.force ) {
if(options.username)
user = await db.read("SELECT * FROM `user` WHERE `username` = ? LIMIT 1", [options.username]);
else if(options.email)
user = await db.read("SELECT * FROM `user` WHERE `email` = ? LIMIT 1", [options.email]);
else if(options.uuid)
user = await db.read("SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1", [options.uuid]);
else if(options.id)
user = await db.read("SELECT * FROM `user` WHERE `id` = ? LIMIT 1", [options.id]);
else if(options.referral_code)
user = await db.read("SELECT * FROM `user` WHERE `referral_code` = ? LIMIT 1", [options.referral_code]);
}
if(!user || !user[0]){
if(options.username)
@@ -679,7 +681,7 @@ const get_descendants_0 = async (path, user, depth, return_thumbnail = false) =>
[user.id]
);
// users that have shared files/dirs with this user
sharing_users = await db.read(
const sharing_users = await db.read(
`SELECT DISTINCT(owner_user_id), user.username
FROM share
INNER JOIN user ON user.id = share.owner_user_id
@@ -717,7 +719,7 @@ const get_descendants_0 = async (path, user, depth, return_thumbnail = false) =>
return [];
// shared files/dirs with this user
shared_fsentries = await db.read(
const shared_fsentries = await db.read(
`SELECT
fsentries.id, fsentries.user_id, fsentries.uuid, fsentries.parent_uid, fsentries.bucket, fsentries.bucket_region,
fsentries.name, fsentries.shortcut_to, fsentries.is_shortcut, fsentries.metadata, fsentries.is_dir, fsentries.modified,
@@ -897,7 +899,7 @@ const get_descendants = async (...args) => {
if ( ! result || ! result[0] ) {
errors.report('id2path.select', {
alarm: true,
message: `no result for ${entry_uid}: ${e.message}`,
message: `no result for ${entry_uid}`,
extra: {
entry_uid,
}
@@ -951,12 +953,12 @@ function cp(source_path, dest_path, user, overwrite, change_name, check_perms =
throw new Error(`legacy copy function called`);
}
isString = function (variable) {
function isString(variable) {
return typeof variable === 'string' || variable instanceof String;
}
// checks to see if given variable is an object
isObject = function (variable) {
function isObject(variable) {
return variable !== null && typeof variable === 'object';
}
@@ -1128,6 +1130,7 @@ async function deleteUser(user_id){
}
function subdomain(req){
if ( config.experimental_no_subdomain ) return 'api';
return req.hostname.slice(0, -1 * (config.domain.length + 1));
}
@@ -1143,10 +1146,10 @@ async function jwt_auth(req){
else if(req.query && req.query.auth_token)
token = req.query.auth_token;
// Socket
else if(req.handshake && req.handshake.query && req.handshake.query.auth_token)
token = req.handshake.query.auth_token;
else if(req.handshake && req.handshake.auth && req.handshake.auth.auth_token)
token = req.handshake.auth.auth_token;
if(!token)
if(!token || token === 'null')
throw('No auth token found');
else if (typeof token !== 'string')
throw('token must be a string.')
@@ -1154,34 +1157,22 @@ async function jwt_auth(req){
token = token.replace('Bearer ', '')
try{
const jwt = require('jsonwebtoken');
const decoded = jwt.verify(token, config.jwt_secret)
const svc_auth = Context.get('services').get('auth');
const actor = await svc_auth.authenticate_from_token(token);
if ( decoded.type ) {
// This is usually not the correct way to throw an APIError;
// this is a workaround for the existing error handling in auth,
// which is well tested, stable, and legacy (no sense in refactoring)
if ( ! actor.type?.constructor?.name === 'UserActorType' ) {
throw({
message: APIError.create('token_unsupported')
.serialize(),
});
}
/** @type BaseDatabaseAccessService */
const db = services.get('database').get(DB_READ, 'filesystem');
// in the vast majority of cases looking up a user should succeed unless the request is invalid (rare case),
// that's why we first hit up the read replica and if not successful we try the master DB
let user = await db.requireRead('SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1', [decoded.uuid]);
// unsuccessful
if(!user[0])
throw('');
// successful
else {
return {user: user[0], token: token};
}
return {
user: actor.type.user,
token: token,
};
}catch(e){
console.log('ERROR', e);
throw(e.message);
}
}
@@ -1556,56 +1547,16 @@ async function generate_system_fsentries(user){
}
function send_email_verification_code(email_confirm_code, email){
const nodemailer = require("nodemailer");
// send email notif
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
transporter.sendMail({
from: '"Puter" [email protected]', // sender address
to: email, // list of receivers
subject: `${hyphenize_confirm_code(email_confirm_code)} is your confirmation code`, // Subject line
html: `<p>Hi there,</p>
<p><strong>${hyphenize_confirm_code(email_confirm_code)}</strong> is your email confirmation code.</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
});
const svc_email = Context.get('services').get('email');
svc_email.send_email({ email }, 'email_verification_code', {
code: hyphenize_confirm_code(email_confirm_code),
})
}
function send_email_verification_token(email_confirm_token, email, user_uuid){
const nodemailer = require("nodemailer");
// send email notif
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
let link = `${config.origin}/confirm-email-by-token?user_uuid=${user_uuid}&token=${email_confirm_token}`;
transporter.sendMail({
from: '"Puter" [email protected]', // sender address
to: email, // list of receivers
subject: `Please confirm your email`, // Subject line
html: `<p>Hi there,</p>
<p>Please confirm your email address using this link: <strong><a href="${link}">${link}</a></strong>.</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
});
const svc_email = Context.get('services').get('email');
const link = `${config.origin}/confirm-email-by-token?user_uuid=${user_uuid}&token=${email_confirm_token}`;
svc_email.send_email({ email }, 'email_verification_link', { link });
}
async function generate_random_username(){
@@ -1819,7 +1770,15 @@ async function suggest_app_for_fsentry(fsentry, options){
monitor.end();
// return list
return suggested_apps;
return suggested_apps.filter((suggested_app, pos, self) => {
// Remove any null values caused by calling `get_app()` for apps that don't exist.
// This happens on self-host because we don't include `code`, among others.
if (!suggested_app)
return false;
// Remove any duplicate entries
return self.indexOf(suggested_app) === pos;
});
}
function build_item_object(item){
@@ -1858,7 +1817,7 @@ async function get_taskbar_items(user) {
try {
taskbar_items_from_db = JSON.parse(user.taskbar_items);
}catch(e){
// ignore errors
}
}
+11 -20
View File
@@ -17,35 +17,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
"use strict"
const APIError = require('../api/APIError');
const {jwt_auth} = require('../helpers');
const { UserActorType } = require('../services/auth/Actor');
const { DB_WRITE } = require('../services/database/consts');
const { Context } = require('../util/context');
const auth2 = require('./auth2');
const auth = async (req, res, next)=>{
let auth2_ok = false;
try{
let auth_res = await jwt_auth(req);
// Delegate to new middleware
await auth2(req, res, () => { auth2_ok = true; });
if ( ! auth2_ok ) return;
// is account suspended?
if(auth_res.user.suspended)
return res.status(401).send({error: 'Account suspended'});
// successful auth
req.user = auth_res.user;
req.token = auth_res.token;
// let's add it to the context too
try {
const x = Context.get();
x.set('user', req.user);
} catch (e) {
console.error(e);
// Everything using the old reference to the auth middleware
// should only allow session tokens
if ( ! (req.actor.type instanceof UserActorType) ) {
throw APIError.create('forbidden');
}
// record as daily active users
const db = req.services.get('database').get(DB_WRITE, 'auth');
db.write('UPDATE `user` SET `last_activity_ts` = now() WHERE id=? LIMIT 1', [req.user.id]);
// go to next
next();
}
// auth failed
+38
View File
@@ -18,8 +18,24 @@
*/
const APIError = require("../api/APIError");
const config = require("../config");
const { UserActorType } = require("../services/auth/Actor");
const { LegacyTokenError } = require("../services/auth/AuthService");
const { Context } = require("../util/context");
// The "/whoami" endpoint is a special case where we want to allow
// a legacy token to be used for authentication. The "/whoami"
// endpoint will then return a new token for further requests.
//
const is_whoami = (req) => {
if ( ! config.legacy_token_migrate ) return;
if ( req.path !== '/whoami' ) return;
// const subdomain = req.subdomains[res.subdomains.length - 1];
// if ( subdomain !== 'api' ) return;
return true;
}
// TODO: Allow auth middleware to be used without requiring
// authentication. This will allow us to use the auth middleware
// in endpoints that do not require authentication, but can
@@ -47,8 +63,10 @@ const auth2 = async (req, res, next) => {
if(!token) {
APIError.create('token_missing').write(res);
return;
} else if (typeof token !== 'string') {
APIError.create('token_auth_failed').write(res);
return;
} else {
token = token.replace('Bearer ', '')
}
@@ -70,6 +88,26 @@ const auth2 = async (req, res, next) => {
e.write(res);
return;
}
if ( e instanceof LegacyTokenError && is_whoami(req) ) {
const new_info = await svc_auth.check_session(token, {
req,
from_upgrade: true,
})
context.set('actor', new_info.actor);
context.set('user', new_info.user);
req.new_token = new_info.token;
req.token = new_info.token;
req.user = new_info.user;
req.actor = new_info.actor;
res.cookie(config.cookie_name, new_info.token, {
sameSite: 'none',
secure: true,
httpOnly: true,
});
next();
return;
}
const re = APIError.create('token_auth_failed');
re.write(res);
return;
+1 -1
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { WeakConstructorTrait } = require("../traits/WeakConstructorTrait");
const { Eq, And } = require("./query/query");
const { Entity } = require("./entitystorage/Entity");
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { instance_ } = require("../../monitor/PerformanceMonitor");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
const { Property } = require("./Property");
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
class PropType extends AdvancedBase {
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
class Property extends AdvancedBase {
+12 -3
View File
@@ -23,7 +23,7 @@ const { AppUnderUserActorType } = require("../../services/auth/Actor");
const { DB_WRITE } = require("../../services/database/consts");
const { Context } = require("../../util/context");
const { origin_from_url } = require("../../util/urlutil");
const { Eq, Or } = require("../query/query");
const { Eq, Like, Or } = require("../query/query");
const { BaseES } = require("./BaseES");
const uuidv4 = require('uuid').v4;
@@ -34,13 +34,19 @@ class AppES extends BaseES {
const services = this.context.get('services');
this.db = services.get('database').get(DB_WRITE, 'apps');
},
async create_predicate (id) {
async create_predicate (id, ...args) {
if ( id === 'user-can-edit' ) {
return new Eq({
key: 'owner',
value: Context.get('user').id,
});
}
if ( id === 'name-like' ) {
return new Like({
key: 'name',
value: args[0],
});
}
},
async delete (uid, extra) {
const svc_appInformation = this.context.get('services').get('app-information');
@@ -187,7 +193,10 @@ class AppES extends BaseES {
const subdomain = await entity.get('subdomain');
const user = Context.get('user');
let subdomain_res = await this.db.write(
`INSERT IGNORE INTO subdomains
`INSERT ${this.db.case({
mysql: 'IGNORE',
sqlite: 'OR IGNORE',
})} INTO subdomains
(subdomain, user_id, root_dir_id, uuid) VALUES
( ?, ?, ?, ?)`,
[
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
const { Context } = require("../../util/context");
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
class Entity extends AdvancedBase {
+20 -4
View File
@@ -16,13 +16,13 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { BaseES } = require("./BaseES");
const APIError = require("../../api/APIError");
const { Entity } = require("./Entity");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
const { And, Or, Eq, Predicate, Null, PredicateUtil } = require("../query/query");
const { And, Or, Eq, Like, Null, Predicate, PredicateUtil } = require("../query/query");
const { DB_WRITE } = require("../../services/database/consts");
class RawCondition extends AdvancedBase {
@@ -94,7 +94,7 @@ class SQLES extends BaseES {
}
const values = [];
if ( predicate ) values.push(...predicate.values);
if ( predicate ) values.push(...(predicate.values || []));
if ( this.debug ) {
this.log.info('-> SQL STMT', { stmt, values });
@@ -219,7 +219,7 @@ class SQLES extends BaseES {
console.log('SQL STMT', stmt);
console.log('SQL VALS', execute_vals);
const res = await db.write(
const res = await this.db.write(
stmt, execute_vals
);
@@ -355,6 +355,22 @@ class SQLES extends BaseES {
return new RawCondition({ sql, values });
}
if ( om_query instanceof Like ) {
const key = om_query.key;
let value = om_query.value;
const prop = this.om.properties[key];
value = await prop.sql_reference(value);
const options = prop.descriptor.sql ?? {};
const col_name = options.column_name ?? prop.name;
const sql = `${col_name} LIKE ?`;
const values = [value];
return new RawCondition({ sql, values });
}
}
}
}
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { BaseES } = require("./BaseES");
const APIError = require("../../api/APIError");
@@ -86,6 +86,7 @@ class ValidationES extends BaseES {
} catch ( e ) {
if ( ! (e instanceof APIError) ) {
console.log('THIS IS HAPPENING', e);
// eslint-disable-next-line no-ex-assign
e = APIError.create('field_invalid', null, {
key: prop.name,
converted_from_another_error: true,
+1
View File
@@ -51,6 +51,7 @@ module.exports = {
maxlen: 7000,
},
maximize_on_start: 'flag',
background: 'flag',
subdomain: {
type: 'string',
transient: true,
+1 -1
View File
@@ -163,7 +163,7 @@ module.exports = {
},
async adapt (value, { descriptor }) {
if ( descriptor.debug ) {
debugger;
debugger; // eslint-disable-line no-debugger
}
if ( ! descriptor.service ) return value;
if ( ! value ) return null;
+11 -1
View File
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { AdvancedBase } = require("@heyputer/puter-js-common");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
class Predicate extends AdvancedBase {
@@ -50,6 +50,15 @@ class Eq extends Predicate {
}
}
class Like extends Predicate {
async check (entity) {
// Convert SQL LIKE pattern to RegExp
// TODO: Support escaping the pattern characters
const regex = new RegExp(this.value.replaceAll('%', '.*').replaceAll('_', '.'), 'i');
return regex.test(await entity.get(this.key));
}
}
Predicate.prototype.and = function (other) {
return new And({ children: [this, other] });
}
@@ -105,4 +114,5 @@ module.exports = {
And,
Or,
Eq,
Like,
};
+27 -10
View File
@@ -26,6 +26,7 @@ const auth = require('../middleware/auth.js');
const { generate_puter_page_html } = require('../temp/puter_page_loader');
const { Context } = require('../util/context');
const { DB_READ } = require('../services/database/consts');
const { PathBuilder } = require('../util/pathutil.js');
let auth_user;
@@ -46,7 +47,7 @@ router.all('*', async function(req, res, next) {
// cloud.js must be accessible globally regardless of subdomain
// --------------------------------------
else if (path === '/cloud.js') {
return res.sendFile(_path.join(__dirname, '../../puter.js/alpha.js'), function (err) {
return res.sendFile(_path.join(__dirname, config.defaultjs_asset_path, 'puter.js/alpha.js'), function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /cloud.js')
}
@@ -56,14 +57,14 @@ router.all('*', async function(req, res, next) {
// /puter.js/v1 must be accessible globally regardless of subdomain
// --------------------------------------
else if (path === '/puter.js/v1' || path === '/puter.js/v1/') {
return res.sendFile(_path.join(__dirname, '../../puter.js/v1.js'), function (err) {
return res.sendFile(_path.join(__dirname, config.defaultjs_asset_path, 'puter.js/v1.js'), function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /puter.js')
}
});
}
else if (path === '/puter.js/v2' || path === '/puter.js/v2/') {
return res.sendFile(_path.join(__dirname, '../../puter.js/v2.js'), function (err) {
return res.sendFile(_path.join(__dirname, config.defaultjs_asset_path, 'puter.js/v2.js'), function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /puter.js')
}
@@ -74,14 +75,14 @@ router.all('*', async function(req, res, next) {
// --------------------------------------
else if( subdomain === 'js'){
if (path === '/v1' || path === '/v1/') {
return res.sendFile(_path.join(__dirname, '../../puter.js/v1.js'), function (err) {
return res.sendFile(_path.join(__dirname, config.defaultjs_asset_path, 'puter.js/v1.js'), function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /puter.js')
}
});
}
if (path === '/v2' || path === '/v2/') {
return res.sendFile(_path.join(__dirname, '../../puter.js/v2.js'), function (err) {
return res.sendFile(_path.join(__dirname, config.defaultjs_asset_path, 'puter.js/v2.js'), function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /puter.js')
}
@@ -176,7 +177,7 @@ router.all('*', async function(req, res, next) {
const user = await get_user({uuid: req.query.user_uuid})
// more validation
if(user === undefined || user === null || user === false)
if(!user)
h += '<p style="text-align:center; color:red;">User not found.</p>';
else if(user.unsubscribed === 1)
h += '<p style="text-align:center; color:green;">You are already unsubscribed.</p>';
@@ -208,7 +209,7 @@ router.all('*', async function(req, res, next) {
const {get_user} = require('../helpers')
// get user
const user = await get_user({uuid: req.query.user_uuid})
const user = await get_user({uuid: req.query.user_uuid, force: true})
// more validation
if(user === undefined || user === null || user === false)
@@ -219,6 +220,13 @@ router.all('*', async function(req, res, next) {
h += '<p style="text-align:center; color:red;">invalid token.</p>';
// mark user as confirmed
else{
// If other users have the same unconfirmed email, revoke it
await db.write(
'UPDATE `user` SET `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `unconfirmed_change_email` = ?',
[user.email],
);
// update user
await db.write(
"UPDATE `user` SET `email_confirmed` = 1, `requires_email_confirmation` = 0 WHERE id = ?",
[user.id]
@@ -246,6 +254,7 @@ router.all('*', async function(req, res, next) {
// /assets/
// ------------------------
else if (path.startsWith('/assets/')) {
path = PathBuilder.resolve(path);
return res.sendFile(path, { root: __dirname + '../../public' }, function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /public/')
@@ -296,8 +305,11 @@ router.all('*', async function(req, res, next) {
const APP_ORIGIN = config.origin;
const API_ORIGIN = config.api_base_url;
return res.send(generate_puter_page_html({
env: config.env,
app_origin: APP_ORIGIN,
api_origin: API_ORIGIN,
use_bundled_gui: config.use_bundled_gui,
manifest,
gui_path: config.assets.gui,
@@ -335,7 +347,7 @@ router.all('*', async function(req, res, next) {
// /dist/...
else if(path.startsWith('/dist/') || path.startsWith('/src/')){
path = _path.resolve(path);
path = PathBuilder.resolve(path);
return res.sendFile(path, {root: config.assets.gui}, function(err){
if(err && err.statusCode){
return res.status(err.statusCode).send('Error /gui/dist/')
@@ -345,6 +357,7 @@ router.all('*', async function(req, res, next) {
// All other paths
else{
path = PathBuilder.resolve(path);
return res.sendFile(path, {root: _path.join(config.assets.gui, 'src')}, function(err){
if(err && err.statusCode){
return res.status(err.statusCode).send('Error /gui/')
@@ -361,7 +374,11 @@ router.all('*', async function(req, res, next) {
subdomain === 'draw' || subdomain === 'camera' || subdomain === 'recorder' ||
subdomain === 'dev-center' || subdomain === 'terminal'){
let root = _path.join(__dirname, '../../apps/', subdomain);
let root = PathBuilder
.add(__dirname)
.add(config.defaultjs_asset_path, { allow_traversal: true })
.add('apps').add(subdomain)
.build();
if ( subdomain === 'docs' ) root += '/dist';
root = _path.normalize(root);
@@ -399,7 +416,7 @@ router.all('*', async function(req, res, next) {
});
} catch (e) {
console.error('error from sendFile', e);
return res.status(err.statusCode).send('Error /apps/')
return res.status(e.statusCode).send('Error /apps/')
}
}
// --------------------------------------
+3 -1
View File
@@ -38,7 +38,7 @@ router.get('/apps', auth, express.json({limit: '50mb'}), async (req, res, next)=
const db = req.services.get('database').get(DB_READ, 'apps');
let apps_res = await dbrr.read(
let apps_res = await db.read(
`SELECT * FROM apps WHERE owner_user_id = ? ORDER BY timestamp DESC`,
[req.user.id]
);
@@ -72,6 +72,7 @@ router.get('/apps', auth, express.json({limit: '50mb'}), async (req, res, next)=
icon: apps_res[i].icon,
index_url: apps_res[i].index_url,
godmode: apps_res[i].godmode,
background: apps_res[i].background,
maximize_on_start: apps_res[i].maximize_on_start,
filetype_associations: filetype_associations,
...stats,
@@ -111,6 +112,7 @@ router.get('/apps/:name', auth, express.json({limit: '50mb'}), async (req, res,
title: app.title,
icon: app.icon,
godmode: app.godmode,
background: app.background,
maximize_on_start: app.maximize_on_start,
index_url: app.index_url,
};
@@ -0,0 +1,123 @@
const APIError = require("../../api/APIError");
const eggspress = require("../../api/eggspress");
const { get_user } = require("../../helpers");
const { UserActorType } = require("../../services/auth/Actor");
const { DB_WRITE } = require("../../services/database/consts");
const { Context } = require("../../util/context");
module.exports = eggspress('/auth/configure-2fa/:action', {
subdomain: 'api',
auth2: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const action = req.params.action;
const x = Context.get();
// Only users can configure 2FA
const actor = Context.get('actor');
if ( ! (actor.type instanceof UserActorType) ) {
throw APIError.create('forbidden');
}
const user = actor.type.user;
const actions = {};
const db = await x.get('services').get('database').get(DB_WRITE, '2fa');
actions.setup = async () => {
const user = await get_user({ id: req.user.id, force: true });
if ( user.otp_enabled ) {
throw APIError.create('2fa_already_enabled');
}
const svc_otp = x.get('services').get('otp');
// generate secret
const result = svc_otp.create_secret(user.username);
// generate recovery codes
result.codes = [];
for ( let i = 0; i < 10; i++ ) {
result.codes.push(svc_otp.create_recovery_code());
}
const hashed_recovery_codes = result.codes.map(code => {
const crypto = require('crypto');
const hash = crypto
.createHash('sha256')
.update(code)
.digest('base64')
// We're truncating the hash for easier storage, so we have 128
// bits of entropy instead of 256. This is plenty for recovery
// codes, which have only 48 bits of entropy to begin with.
.slice(0, 22);
return hash;
});
// update user
await db.write(
`UPDATE user SET otp_secret = ?, otp_recovery_codes = ? WHERE uuid = ?`,
[result.secret, hashed_recovery_codes.join(','), user.uuid]
);
req.user.otp_secret = result.secret;
req.user.otp_recovery_codes = hashed_recovery_codes.join(',');
user.otp_secret = result.secret;
user.otp_recovery_codes = hashed_recovery_codes.join(',');
return result;
};
// IMPORTANT: only use to verify the user's 2FA setup;
// this should never be used to verify the user's 2FA code
// for authentication purposes.
actions.test = async () => {
const user = req.user;
const svc_otp = x.get('services').get('otp');
const code = req.body.code;
const ok = svc_otp.verify(user.username, user.otp_secret, code);
return { ok };
};
actions.enable = async () => {
const svc_edgeRateLimit = req.services.get('edge-rate-limit');
if ( ! svc_edgeRateLimit.check('enable-2fa') ) {
return res.status(429).send('Too many requests.');
}
const user = await get_user({ id: req.user.id, force: true });
// Verify that 2FA isn't already enabled
if ( user.otp_enabled ) {
throw APIError.create('2fa_already_enabled');
}
// Verify that TOTP secret was set (configuration step not skipped)
if ( ! user.otp_secret ) {
throw APIError.create('2fa_not_configured');
}
await db.write(
`UPDATE user SET otp_enabled = 1 WHERE uuid = ?`,
[user.uuid]
);
// update cached user
req.user.otp_enabled = 1;
const svc_email = req.services.get('email');
await svc_email.send_email({ email: user.email }, 'enabled_2fa', {
username: user.username,
});
return {};
};
if ( ! actions[action] ) {
throw APIError.create('invalid_action', null, { action });
}
const result = await actions[action]();
res.json(result);
});
@@ -0,0 +1,43 @@
const eggspress = require("../../api/eggspress");
const { deleteUser, invalidate_cached_user } = require("../../helpers");
const config = require("../../config");
module.exports = eggspress("/delete-own-user", {
subdomain: "api",
auth: true,
allowedMethods: ["POST"],
}, async (req, res, next) => {
const bcrypt = require('bcrypt');
const validate_request = async () => {
const user = req.user;
// `user` should always have a value, but this is checked
// any way in case the auth middleware is broken.
if ( ! user ) return false;
// temporary users don't require password verification
if ( ! user.email && ! user.password ) {
return true;
}
if ( ! req.body.password ) return false;
if ( ! user || ! user.password ) return false;
if ( ! await bcrypt.compare(req.body.password, req.user.password) ) {
return false;
}
return true;
}
if ( ! await validate_request() ) {
return res.status(400).send({ success: false });
}
res.clearCookie(config.cookie_name);
await deleteUser(req.user.id);
invalidate_cached_user(req.user);
return res.send({ success: true });
});
@@ -0,0 +1,30 @@
const APIError = require("../../api/APIError");
const eggspress = require("../../api/eggspress");
const { UserActorType } = require("../../services/auth/Actor");
const { Context } = require("../../util/context");
module.exports = eggspress('/auth/grant-user-user', {
subdomain: 'api',
auth2: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const x = Context.get();
const svc_permission = x.get('services').get('permission');
// Only users can grant user-user permissions
const actor = Context.get('actor');
if ( ! (actor.type instanceof UserActorType) ) {
throw APIError.create('forbidden');
}
if ( ! req.body.target_username ) {
throw APIError.create('field_missing', null, { key: 'target_username' });
}
await svc_permission.grant_user_user_permission(
actor, req.body.target_username, req.body.permission,
req.body.extra || {}, req.body.meta || {}
);
res.json({});
});
@@ -17,10 +17,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const eggspress = require("../../api/eggspress");
const { get_app } = require("../../helpers");
const { get_app, get_user } = require("../../helpers");
const { UserActorType } = require("../../services/auth/Actor");
const { DB_READ } = require("../../services/database/consts");
const { Context } = require("../../util/context");
const APIError = require('../../api/APIError');
module.exports = eggspress('/auth/list-permissions', {
subdomain: 'api',
@@ -38,29 +39,73 @@ module.exports = eggspress('/auth/list-permissions', {
const db = x.get('services').get('database').get(DB_READ, 'permissions');
const permissions = [];
const permissions = {};
const rows = await db.read(
'SELECT * FROM `user_to_app_permissions` WHERE user_id=?',
[ actor.type.user.id ]
);
{
permissions.myself_to_app = [];
for ( const row of rows ) {
const app = await get_app({ id: row.app_id });
const rows = await db.read(
'SELECT * FROM `user_to_app_permissions` WHERE user_id=?',
[ actor.type.user.id ]
);
delete app.id;
delete app.approved_for_listing;
delete app.approved_for_opening_items;
delete app.godmode;
delete app.owner_user_id;
for ( const row of rows ) {
const app = await get_app({ id: row.app_id });
const permission = {
app,
permission: row.permission,
extra: row.extra
};
delete app.id;
delete app.approved_for_listing;
delete app.approved_for_opening_items;
delete app.godmode;
delete app.owner_user_id;
permissions.push(permission);
const permission = {
app,
permission: row.permission,
extra: row.extra
};
permissions.myself_to_app.push(permission);
}
}
{
permissions.myself_to_user = [];
const rows = await db.read(
'SELECT * FROM `user_to_user_permissions` WHERE issuer_user_id=?',
[ actor.type.user.id ]
);
for ( const row of rows ) {
const user = await get_user({ id: row.holder_user_id });
const permission = {
user: user.username,
permission: row.permission,
extra: row.extra
};
permissions.myself_to_user.push(permission);
}
}
{
permissions.user_to_myself = [];
const rows = await db.read(
'SELECT * FROM `user_to_user_permissions` WHERE holder_user_id=?',
[ actor.type.user.id ]
);
for ( const row of rows ) {
const user = await get_user({ id: row.issuer_user_id });
const permission = {
user: user.username,
permission: row.permission,
extra: row.extra
};
permissions.user_to_myself.push(permission);
}
}
res.json(permissions);
@@ -0,0 +1,24 @@
const eggspress = require("../../api/eggspress");
const { UserActorType } = require("../../services/auth/Actor");
const { Context } = require("../../util/context");
const APIError = require('../../api/APIError');
module.exports = eggspress('/auth/list-sessions', {
subdomain: 'api',
auth2: true,
allowedMethods: ['GET'],
}, async (req, res, next) => {
const x = Context.get();
const svc_auth = x.get('services').get('auth');
// Only users can list their own sessions
// apps, access tokens, etc should NEVER access this
const actor = x.get('actor');
if ( ! (actor.type instanceof UserActorType) ) {
throw APIError.create('forbidden');
}
const sessions = await svc_auth.list_sessions(actor);
res.json(sessions);
});
@@ -0,0 +1,33 @@
const APIError = require("../../api/APIError");
const eggspress = require("../../api/eggspress");
const { UserActorType } = require("../../services/auth/Actor");
const { Context } = require("../../util/context");
module.exports = eggspress('/auth/revoke-session', {
subdomain: 'api',
auth2: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const x = Context.get();
const svc_auth = x.get('services').get('auth');
// Only users can list their own sessions
// apps, access tokens, etc should NEVER access this
const actor = x.get('actor');
if ( ! (actor.type instanceof UserActorType) ) {
throw APIError.create('forbidden');
}
// Ensure valid UUID
if ( ! req.body.uuid || typeof req.body.uuid !== 'string' ) {
throw APIError.create('field_invalid', null, {
key: 'uuid',
expected: 'string'
});
}
const sessions = await svc_auth.revoke_session(
actor, req.body.uuid);
res.json({ sessions });
});
@@ -19,6 +19,7 @@
const eggspress = require("../../api/eggspress");
const { UserActorType } = require("../../services/auth/Actor");
const { Context } = require("../../util/context");
const APIError = require('../../api/APIError');
module.exports = eggspress('/auth/revoke-user-app', {
subdomain: 'api',
@@ -0,0 +1,31 @@
const APIError = require("../../api/APIError");
const eggspress = require("../../api/eggspress");
const { UserActorType } = require("../../services/auth/Actor");
const { Context } = require("../../util/context");
module.exports = eggspress('/auth/revoke-user-user', {
subdomain: 'api',
auth2: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const x = Context.get();
const svc_permission = x.get('services').get('permission');
// Only users can grant user-user permissions
const actor = Context.get('actor');
if ( ! (actor.type instanceof UserActorType) ) {
throw APIError.create('forbidden');
}
if ( ! req.body.target_username ) {
throw APIError.create('field_missing', null, { key: 'target_username' });
}
await svc_permission.revoke_user_user_permission(
actor, req.body.target_username, req.body.permission,
req.body.meta || {}
);
res.json({});
});
+42 -57
View File
@@ -23,83 +23,68 @@ const eggspress = require('../api/eggspress.js');
const APIError = require('../api/APIError.js');
const { DB_READ, DB_WRITE } = require('../services/database/consts.js');
const CHANGE_EMAIL_START = eggspress('/change_email/start', {
subdomain: 'api',
auth: true,
verified: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const user = req.user;
const new_email = req.body.new_email;
const config = require('../config.js');
// TODO: DRY: signup.js
// validation
if( ! new_email ) {
throw APIError.create('field_missing', null, { key: 'new_email' });
}
if ( typeof new_email !== 'string' ) {
throw APIError.create('field_invalid', null, {
key: 'new_email', expected: 'a valid email address' });
}
if ( ! validator.isEmail(new_email) ) {
throw APIError.create('field_invalid', null, {
key: 'new_email', expected: 'a valid email address' });
}
// check if email is already in use
const svc_mysql = req.services.get('mysql');
const db = req.services.get('database').get(DB_WRITE, 'auth');
const rows = await db.read(
'SELECT COUNT(*) AS `count` FROM `user` WHERE `email` = ?',
[new_email]
);
if ( rows[0].count > 0 ) {
throw APIError.create('email_already_in_use', null, { email: new_email });
}
// generate confirmation token
const token = crypto.randomBytes(4).toString('hex');
// update user
await db.write(
'UPDATE `user` SET `unconfirmed_change_email` = ?, `change_email_confirm_token` = ? WHERE `id` = ?',
[new_email, token, user.id]
);
});
const jwt = require('jsonwebtoken');
const { invalidate_cached_user_by_id } = require('../helpers.js');
const CHANGE_EMAIL_CONFIRM = eggspress('/change_email/confirm', {
subdomain: 'api',
auth: true,
verified: true,
allowedMethods: ['POST'],
allowedMethods: ['GET'],
}, async (req, res, next) => {
const user = req.user;
const token = req.body.token;
const jwt_token = req.query.token;
if ( ! token ) {
if ( ! jwt_token ) {
throw APIError.create('field_missing', null, { key: 'token' });
}
const svc_mysql = req.services.get('mysql');
const dbrr = svc_mysql.get(DB_MODE_READ, 'change-email-confirm');
const [rows] = await dbrr.promise().query(
const svc_edgeRateLimit = req.services.get('edge-rate-limit');
if ( ! svc_edgeRateLimit.check('change-email-confirm') ) {
return res.status(429).send('Too many requests.');
}
const { token, user_id } = jwt.verify(jwt_token, config.jwt_secret);
const db = req.services.get('database').get(DB_WRITE, 'auth');
const rows = await db.read(
'SELECT `unconfirmed_change_email` FROM `user` WHERE `id` = ? AND `change_email_confirm_token` = ?',
[user.id, token]
[user_id, token]
);
if ( rows.length === 0 ) {
throw APIError.create('token_invalid');
}
// Scenario: email was confirmed on another account already
const rows2 = await db.read(
'SELECT `id` FROM `user` WHERE `email` = ?',
[rows[0].unconfirmed_change_email]
);
if ( rows2.length > 0 ) {
throw APIError.create('email_already_in_use');
}
// If other users have the same unconfirmed email, revoke it
await db.write(
'UPDATE `user` SET `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `unconfirmed_change_email` = ?',
[rows[0].unconfirmed_change_email]
);
const new_email = rows[0].unconfirmed_change_email;
const db = req.services.get('database').get(DB_WRITE, 'auth');
await db.write(
'UPDATE `user` SET `email` = ?, `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `id` = ?',
[new_email, user.id]
'UPDATE `user` SET `email` = ?, `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL, `pass_recovery_token` = NULL WHERE `id` = ?',
[new_email, user_id]
);
invalidate_cached_user_by_id(user_id);
let socketio = require('../socketio.js').getio();
if(socketio){
socketio.to(user_id).emit('user.email_changed', {})
}
const h = `<p style="text-align:center; color:green;">Your email has been successfully confirmed.</p>`;
return res.send(h);
});
module.exports = app => {
app.use(CHANGE_EMAIL_START);
app.use(CHANGE_EMAIL_CONFIRM);
}
@@ -54,12 +54,21 @@ module.exports = eggspress('/change_username', {
if(await username_exists(req.body.new_username))
throw APIError.create('username_already_in_use', null, { username: req.body.new_username });
const svc_edgeRateLimit = req.services.get('edge-rate-limit');
if ( ! svc_edgeRateLimit.check('change-email-start') ) {
return res.status(429).send('Too many requests.');
}
const db = Context.get('services').get('database').get(DB_WRITE, 'auth');
// Has the user already changed their username twice this month?
const rows = await db.read(
'SELECT COUNT(*) AS `count` FROM `user_update_audit` ' +
'WHERE `user_id`=? AND `reason`=? AND `created_at` > DATE_SUB(NOW(), INTERVAL 1 MONTH)',
'WHERE `user_id`=? AND `reason`=? AND ' +
db.case({
mysql: '`created_at` > DATE_SUB(NOW(), INTERVAL 1 MONTH)',
sqlite: "`created_at` > datetime('now', '-1 month')",
}),
[ req.user.id, 'change_username' ]
);
@@ -22,6 +22,7 @@ const { invalidate_cached_user } = require('../helpers');
const router = new express.Router();
const auth = require('../middleware/auth.js');
const { DB_WRITE } = require('../services/database/consts');
const APIError = require('../api/APIError.js');
// -----------------------------------------------------------------------//
// POST /confirm-email
@@ -34,6 +35,11 @@ router.post('/confirm-email', auth, express.json(), async (req, res, next)=>{
if(!req.body.code)
req.status(400).send('code is required');
const svc_edgeRateLimit = req.services.get('edge-rate-limit');
if ( ! svc_edgeRateLimit.check('confirm-email') ) {
return res.status(429).send('Too many requests.');
}
// Modules
const db = req.services.get('database').get(DB_WRITE, 'auth');
@@ -43,6 +49,22 @@ router.post('/confirm-email', auth, express.json(), async (req, res, next)=>{
// Set expiry for rate limit
kv.expire(`confirm-email|${req.ip}|${req.body.email ?? req.body.username}`, 60 * 10, 'NX')
// Scenario: email was confirmed on another account already
const rows = await db.read(
'SELECT `id` FROM `user` WHERE `email` = ? AND `email_confirmed` = 1',
[req.body.email],
);
if ( rows.length > 0 ) {
APIError.create('email_already_in_use').write(res);
return;
}
// If other users have the same unconfirmed email, revoke it
await db.write(
'UPDATE `user` SET `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `unconfirmed_change_email` = ?',
[req.user.email],
);
if(req.body.code === req.user.email_confirm_code) {
await db.write(
"UPDATE `user` SET `email_confirmed` = 1, `requires_email_confirmation` = 0 WHERE id = ? LIMIT 1",
+7 -18
View File
@@ -32,10 +32,6 @@ router.post('/contactUs', auth, express.json(), async (req, res, next)=>{
if(require('../helpers').subdomain(req) !== 'api')
next();
// check if user is verified
if((config.strict_email_verification_required || req.user.requires_email_confirmation) && !req.user.email_confirmed)
return res.status(400).send({code: 'account_is_not_verified', message: 'Account is not verified'});
// message is required
if(!req.body.message)
return res.status(400).send({message: 'message is required'})
@@ -46,6 +42,11 @@ router.post('/contactUs', auth, express.json(), async (req, res, next)=>{
else if(req.body.message.length > 100000)
return res.status(400).send({message: 'message is too long'})
const svc_edgeRateLimit = req.services.get('edge-rate-limit');
if ( ! svc_edgeRateLimit.check('contact-us') ) {
return res.status(429).send('Too many requests.');
}
// modules
const db = req.services.get('database').get(DB_WRITE, 'feedback');
@@ -66,20 +67,8 @@ router.post('/contactUs', auth, express.json(), async (req, res, next)=>{
let user = await get_user({id: req.user.id});
// send email to support
const nodemailer = require("nodemailer");
// send email notif
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
transporter.sendMail({
const svc_email = req.services.get('email');
svc_email.sendMail({
from: '"Puter" [email protected]', // sender address
to: '[email protected]', // list of receivers
replyTo: user.email === null ? undefined : user.email,
+6 -6
View File
@@ -21,8 +21,9 @@ const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth.js');
const config = require('../config');
const { DB_WRITE } = require('../services/database/consts.js');
// -----------------------------------------------------------------------//
// -----------------------------------------------------------------------//
// POST /delete-site
// -----------------------------------------------------------------------//
router.post('/delete-site', auth, express.json(), async (req, res, next)=>{
@@ -39,13 +40,12 @@ router.post('/delete-site', auth, express.json(), async (req, res, next)=>{
return res.status(400).send('site_uuid is required')
// modules
const {} = require('../helpers');
const db = require('../db/mysql.js')
const db = req.services.get('database').get(DB_WRITE, 'subdomains:legacy');
await db.promise().execute(
`DELETE FROM subdomains WHERE user_id = ? AND uuid = ?`,
await db.write(
`DELETE FROM subdomains WHERE user_id = ? AND uuid = ?`,
[req.user.id, req.body.site_uuid]
);
);
res.send({});
})
+8 -2
View File
@@ -22,6 +22,8 @@ const config = require('../config.js');
const router = new express.Router();
const auth = require('../middleware/auth.js');
// TODO: Why is this both a POST and a GET?
// -----------------------------------------------------------------------//
// POST /df
// -----------------------------------------------------------------------//
@@ -35,11 +37,13 @@ router.post('/df', auth, express.json(), async (req, response, next)=>{
return response.status(400).send({code: 'account_is_not_verified', message: 'Account is not verified'});
const {df} = require('../helpers');
const svc_hostDiskUsage = req.services.get('host-disk-usage', { optional: true });
try{
// auth
response.send({
used: parseInt(await df(req.user.id)),
capacity: (req.user.free_storage === undefined || req.user.free_storage === null) ? config.storage_capacity : req.user.free_storage,
capacity: config.is_storage_limited ? (req.user.free_storage === undefined || req.user.free_storage === null) ? config.storage_capacity : req.user.free_storage : config.available_device_storage,
...(svc_hostDiskUsage ? svc_hostDiskUsage.get_extra() : {}),
});
}catch(e){
console.log(e)
@@ -60,11 +64,13 @@ router.get('/df', auth, express.json(), async (req, response, next)=>{
return response.status(400).send({code: 'account_is_not_verified', message: 'Account is not verified'});
const {df} = require('../helpers');
const svc_hostDiskUsage = req.services.get('host-disk-usage', { optional: true });
try{
// auth
response.send({
used: parseInt(await df(req.user.id)),
capacity: (req.user.free_storage === undefined || req.user.free_storage === null) ? config.storage_capacity : req.user.free_storage,
capacity: config.is_storage_limited ? (req.user.free_storage === undefined || req.user.free_storage === null) ? config.storage_capacity : req.user.free_storage : config.available_device_storage,
...(svc_hostDiskUsage ? svc_hostDiskUsage.get_extra() : {}),
});
}catch(e){
console.log(e)
+78
View File
@@ -0,0 +1,78 @@
"use strict"
const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth.js');
const config = require('../config.js');
const fs = require('../middleware/fs.js');
const { DB_WRITE } = require('../services/database/consts.js');
const { NodePathSelector } = require('../filesystem/node/selectors.js');
const { HLRead } = require('../filesystem/hl_operations/hl_read.js');
// -----------------------------------------------------------------------//
// GET /down
// -----------------------------------------------------------------------//
router.post('/down', auth, fs, express.json(), async (req, res, next)=>{
// check subdomain
if(require('../helpers').subdomain(req) !== 'api')
next();
// check if user is verified
if((config.strict_email_verification_required || req.user.requires_email_confirmation) && !req.user.email_confirmed)
return res.status(400).send({code: 'account_is_not_verified', message: 'Account is not verified'});
// check anti-csrf token
const svc_antiCSRF = req.services.get('anti-csrf');
if ( ! svc_antiCSRF.consume_token(req.user.uuid, req.body.anti_csrf) ) {
return res.status(400).json({ message: 'incorrect anti-CSRF token' });
}
// validation
if(!req.query.path)
return res.status(400).send('path is required')
// path must be a string
else if (typeof req.query.path !== 'string')
return res.status(400).send('path must be a string.')
else if(req.query.path.trim() === '')
return res.status(400).send('path cannot be empty')
// modules
const db = req.services.get('database').get(DB_WRITE, 'filesystem');
const _path = require('path');
const {chkperm} = require('../helpers')
const path = _path.resolve('/', req.query.path);
const AWS = require('aws-sdk');
// cannot download the root, because it's a directory!
if(path === '/')
return res.status(400).send('Cannot download a directory.');
// resolve path to its FSEntry
const fsnode = await req.fs.node(new NodePathSelector(path));
// not found
if( ! fsnode.exists() ) {
return res.status(404).send('File not found');
}
// stream data from S3
try{
const hl_read = new HLRead();
const stream = await hl_read.run({
fsNode: fsnode,
user: req.user,
});
// let stream = await s3.getObject({
// Bucket: fsentry.bucket,
// Key: fsentry.uuid, // File name you want to save as in S3
// }).createReadStream().on('error', error => {
// console.log(error);
// });
res.attachment(await fsnode.get('name'));
return stream.pipe(res);
}catch(e){
console.log(e);
return res.type('application/json').status(500).send({message: 'There was an internal problem reading the file.'});
}
})
module.exports = router
@@ -143,7 +143,7 @@ module.exports = eggspress('/drivers/usage', {
// usages.apps.push(usage);
}
for ( k in usages.apps ) {
for ( const k in usages.apps ) {
usages.apps[k] = Object.values(usages.apps[k]);
}
+4 -3
View File
@@ -65,8 +65,9 @@ const script = async function script () {
return await response.json();
};
/* global window */
window.addEventListener('message', async event => {
const { id, interface, method, params } = event.data;
const { id, interface: interface_, method, params } = event.data;
let has_file = false;
for ( const k in params ) {
if ( params[k] instanceof File ) {
@@ -75,11 +76,11 @@ const script = async function script () {
}
}
const result = has_file ? await fcall({
interface_name: interface,
interface_name: interface_,
method_name: method,
params,
}) : await call({
interface_name: interface,
interface_name: interface_,
method_name: method,
params,
});
+20 -15
View File
@@ -19,9 +19,9 @@
"use strict"
const express = require('express');
const router = new express.Router();
const config = require('../config');
const {validate_signature_auth, get_url_from_req, get_descendants, id2path, get_user, sign_file} = require('../helpers');
const { DB_WRITE } = require('../services/database/consts');
const { Context } = require('../util/context');
// -----------------------------------------------------------------------//
// GET /file
@@ -40,6 +40,10 @@ router.get('/file', async (req, res, next)=>{
return res.status(403).send(e);
}
const log = req.services.get('log-service').create('/file');
const errors = req.services.get('error-service').create(log);
// modules
const db = req.services.get('database').get(DB_WRITE, 'filesystem');
const mime = require('mime-types')
@@ -92,7 +96,7 @@ router.get('/file', async (req, res, next)=>{
res.resource_owner = fsentry[0].user_id;
// try to deduce content-type
const contentType = mime.contentType(fsentry[0].name)
const contentType = "application/octet-stream";
// update `accessed`
db.write(
@@ -113,13 +117,17 @@ router.get('/file', async (req, res, next)=>{
// stream data from S3
try{
let stream = await storage.create_read_stream({
key: fsentry[0].uuid,
let stream = await storage.create_read_stream(fsentry[0].uuid, {
bucket: fsentry[0].bucket,
bucket_region: fsentry[0].bucket_region,
});
return stream.pipe(res);
}catch(e){
errors.report('read from storage', {
source: e,
trace: true,
alarm: true,
});
return res.type('application/json').status(500).send({message: 'There was an internal problem reading the file.'});
}
}
@@ -167,25 +175,22 @@ router.get('/file', async (req, res, next)=>{
// HTTP Status 206 for Partial Content
res.writeHead(206, headers);
// init S3
const s3 = new AWS.S3({
accessKeyId: config.s3_access_key,
secretAccessKey: config.s3_secret_key,
region: fsentry[0].bucket_region,
});
try{
let stream = await storage.create_read_stream({
key: fsentry[0].uuid,
const storage = Context.get('storage');
let stream = await storage.create_read_stream(fsentry[0].uuid, {
bucket: fsentry[0].bucket,
bucket_region: fsentry[0].bucket_region,
});
return stream.pipe(res);
}catch(e){
console.log(e)
errors.report('read from storage', {
source: e,
trace: true,
alarm: true,
});
return res.type('application/json').status(500).send({message: 'There was an internal problem reading the file.'});
}
}
})
module.exports = router
module.exports = router
Loaded 100 of 575 files, more files were not shown because too many files have changed in this diff. Show more