`puter.perms.request()` already pooled a permission read and prompted only for what was missing. The raw `puter.ui.requestPermission()` did not, so every caller still on it re-asked the user on each launch — including `perms.requestAppData()`, whose own docs promise the opposite, and the driver-denial retry. - puter.js: `ui.requestPermission()` reads what is held before prompting and resolves true when the whole request is covered. Only in env=app and env=web, the environments that raise a prompt; elsewhere the method still answers false without asking anyone. A check that cannot be made — no token, an unreadable request shape, a failed read, or one that outlasts its timeout — falls through to the prompt rather than standing in for an answer. Public signature unchanged. - GUI: the request-permission popup asks the same question as the app, using the user-app token its own exchange already mints, and skips the dialog when the access is held. This is the one case the SDK cannot settle for itself: a signed-out site holds no token to check with. An origin the browser does not vouch for never reaches the check, since the exchange fails first. Both checks are time-boxed, because each one stands in front of something that is waiting: the popup's gates the dialog, so a stalled read would leave the prompt unshown and the opener pending, and the SDK's spends the browser's transient activation, which a slow read would cost the popup. Note that driver, service and feature scopes are implicitly granted to every app (backend/data/hardcoded-permissions.js), so requests for those now settle silently — the dialog was asking about access the app already had. Consent scopes (email, fs, apps, subdomains, app-data, app-root-dir) are unaffected and still prompt until granted. Fixes a bug this method already had on the way past: `pollDecision` read an undeclared `permission`, so every attempt threw a ReferenceError into its network-failure catch and the COOP-severed-opener recovery burned its full five-minute timeout before answering false. It polls `requested` now, and requires the whole list. Tests: the e2e suite drove its dialogs with an implicitly-held driver permission, so the fixture now asks for a driver nothing implies, fresh per page load, which also removes the cross-test grant carry-over the old revokes worked around. The reconciliation tests ask for the held scope plus an unheld one, since a fully-held request no longer reaches a dialog. Adds a backend contract test for check-permissions under an app-under-user actor, which is what the two new client paths rest on.
The Open-Source Internet Computer!
« LIVE DEMO »
Puter.com
·
App Store
·
Developers
·
X
Puter
Puter is an advanced, open-source, self-hostable internet computer designed to be feature-rich, fast, and highly extensible.
For Users
Puter's goal is to provide you with every app and feature you need to work, create, and play under one roof. From a simple Notepad and Voice Recorder to Spreadsheet and Camera, Puter wants to be the all-in-one solution for your digital life.
For Developers
Puter provides everything you need to build and publish web apps and games. From AI to Cloud Storage and Database to Serverless Workers, Puter has you covered. Puter also helps you get users! Once you build your app, you can publish it on our App Store to reach and monetize users.
Getting Started
💻 Local Development
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
→ This should launch Puter at http://puter.localhost:4100
🚀 Self-Hosting
Linux/macOS
curl -fsSL https://puter.com/selfhost | sh
Windows
irm https://puter.com/selfhost?os=windows | iex
→ For more details, see Self-Hosting Puter.
☁️ Puter.com
Puter is available as a hosted service at puter.com.
Support
Connect with the maintainers and community through these channels:
- Bug report or feature request? Please open an issue.
- X (Twitter): x.com/HeyPuter
- Security issues or abuse reports? security@puter.com
- Email maintainers at hi@puter.com
We are always happy to help you with any questions you may have. Don't hesitate to ask!
License
This repository, including all its contents, sub-projects, modules, and components, is licensed under AGPL-3.0 unless explicitly stated otherwise. Third-party libraries included in this repository may be subject to their own licenses.
Translations
- Arabic / العربية
- Armenian / Հայերեն
- Bengali / বাংলা
- Chinese / 中文
- Danish / Dansk
- English
- Farsi / فارسی
- Finnish / Suomi
- French / Français
- German / Deutsch
- Hebrew/ עברית
- Hindi / हिंदी
- Hungarian / Magyar
- Indonesian / Bahasa Indonesia
- Italian / Italiano
- Japanese / 日本語
- Korean / 한국어
- Malay / Bahasa Malaysia
- Malayalam / മലയാളം
- Dutch / Nederlands
- Polish / Polski
- Odia / ଓଡ଼ିଆ
- Portuguese / Português
- Punjabi / ਪੰਜਾਬੀ
- Romanian / Română
- Russian / Русский
- Spanish / Español
- Swedish / Svenska
- Tamil / தமிழ்
- Telugu / తెలుగు
- Thai / ไทย
- Turkish / Türkçe
- Ukrainian / Українська
- Urdu / اردو
- Vietnamese / Tiếng Việt

