Coder Social home page Coder Social logo

idle-detection's Introduction

User Idle Detection

Read the draft specification.

This proposed API allows developers to add an event listener for when the user becomes idle (e.g. they don’t interact with the keyboard, mouse or touchscreen, when a screensaver activates or when the screen is locked). Unlike solutions based on monitoring input events this capability extends beyond the site's content area (e.g. when users move to a different window or tab).

Native applications and browser extensions (e.g. Chrome apps, Android apps, Firefox extensions, Edge extensions) use idle detection to notify other users that the user is unreachable (e.g. in chat applications), to show timely alerts (e.g. "welcome back" when a user returns to their task) or to pause media (e.g. to save bandwidth when the user is not present).

The API should provide a means to detect the user's idle status (active, idle, locked), and a power-efficient way to be notified of changes to the status without polling from script.

Feedback: WICG Discourse ThreadIssues

Use cases

  • Chat application: presenting a user's status to other users and delivering notifications to the device where the user is active.
  • Showing timely notifications - e.g. deferring displaying feedback until the user returns to an active state.
  • Updating an outdated service worker when there's no unsaved state by triggering reloading of the tab.

Relationship with other APIs

  • As opposed to the requestIdleCallback, this is not about asynchronously scheduling work when the system is idle.
  • As opposed to the Page Visibility API, this API enables detecting idleness even after a page is no longer visible (e.g. after the page is no longer visible, is the user still around? if i showed a notification, would it be perceived?).

Polyfills

Currently, web apps (e.g. Dropbox’s idle.ts) are constrained to their own content area:

  1. costly polling for input events or
  2. listening to visibility changes

Script can't tell today when a user goes idle outside of its content area (e.g. whether a user is on a different tab or logged out of the computer altogether).

Model

The API assumes that there is some level of engagement between the user, user agent, and operating system of the device in use. This is represented in two dimensions:

  1. The user idle state
  • active/idle - the user has / has not interacted with the user agent for some period of time
  1. The screen idle state
  • locked/unlocked - the system has an active screen lock preventing interaction with the user agent

Distinguishing "active" from "idle" requires heuristics that may differ across user, user agent, and operating system. It should also be a reasonably coarse threshold (See Privacy).

The model intentionally does not formally distinguish between interaction with particular content (i.e. the web page in a tab using the API), the user agent as a whole, or the operating system; this definition is left to the user agent.

Example: The user is interacting with an operating system providing multiple virtual desktops. The user may be actively interacting with one virtual desktop, but unable to see the content of another virtual desktop. A user agent presenting content on the second virtual desktop may report an "idle" state rather than an "active" state.

API Design

The API design is largely inspired by the Sensors API. You can find more about alternatives considered here.

WebIDL

dictionary IdleOptions {
  [EnforceRange] unsigned long threshold;
  AbortSignal signal;
};

enum UserIdleState {
    "active",
    "idle"
};

enum ScreenIdleState {
    "locked",
    "unlocked"
};

[
  SecureContext,
  Exposed=(Window,DedicatedWorker)
] interface IdleDetector : EventTarget {
  constructor();
  readonly attribute UserIdleState? userState;
  readonly attribute ScreenIdleState? screenState;
  attribute EventHandler onchange;
  [Exposed=Window] static Promise<PermissionState> requestPermission();
  Promise<void> start(optional IdleOptions options = {});
};

Example

Here is an example of how to use it (more detailed instructions here):

const main = async () => {
  // Feature detection.
  if (!('IdleDetector' in window)) {
    return console.log('IdleDetector is not available.');
  }
  // Request permission to use the feature.
  if ((await IdleDetector.requestPermission() !== 'granted') {
    return console.log('Idle detection permission not granted.');
  }
  try {
    const controller = new AbortController();
    const signal = controller.signal;
    
    const idleDetector = new IdleDetector();
    idleDetector.addEventListener('change', () => {
      console.log(`Idle change: ${idleDetector.userState}, ${idleDetector.screenState}.`);
    });    
    await idleDetector.start({
      threshold: 60000,
      signal,
    });
    console.log('IdleDetector is active.');
    
    window.setTimeout(() => {
      controller.abort();
      console.log('IdleDetector is stopped.');
    }, 120000);
  } catch (err) {
    // Deal with initialization errors like permission denied,
    // running outside of top-level frame, etc.
    console.error(err.name, err.message);
  }
};

main();

Platforms

All platforms (Linux, Windows, macOS, Android, iOS and Chrome OS) support some form of idle detection.

On desktop devices (Chrome OS, Linux, macOS and Windows), a screen saver (from a time when monitors were damaged if the same pixels were lit for an extended period of time) activates after a user-configurable period of inactivity. The operating system may optionally require the user to reauthenticate (i.e. lock the screen) after the screen saver has been activated for a period of time. Both of these events are observable by engines.

On mobile devices (Android and iOS), the screen is dimmed after a few seconds of inactivity (to save battery, not pixels) but this isn't observable by engines (on Android). The screen is eventually turned off (to save further battery) if the user remains inactive for a configurable amount of time (typically 30 seconds), and that is observable by engines. When the screen goes off, the screen is also typically locked (unlockable by Swipe, Pattern, PIN or Password), although it can be configured to be left off but unlocked.

Permissions

The ability to use this API will be controlled by the new ["idle-detection" permission].

Security and Privacy

See answers to the W3C TAG's security & privacy self-review questionnaire in security-privacy-self-assessment.md.

The idle state is a global system property and so care must be taken to prevent this from being used as a cross-origin communication or identification channel. This is similar to other APIs which provide access to system events such as Generic Sensors and Geolocation.

A short idle threshold could be used to identify user behavior in another tab. With a short enough threshold an idle state change could be used to measure typing cadence when the user is in another application and thus leak sensitive data such as passwords.

Users with physical or cognitive impairments may require more time to interact with user agents and content. The API should not allow distinguishing such users, or limiting their ability to interact with content any more than existing observation of UI events.

If an implementation restricts the detection threshold it should also restrict how quickly responses to start() are delivered or ensure that the response is cached or otherwise provide a guarantee that rapid polling does not bypass the restriction on data granularity.

To mitigate the exposure of this global state the API should be restricted to top-level frames with a new "idle-detection" permission. This permission can be delegated to sub-frames via Permissions Policy or the sandbox attribute. The top-level frame requirement significantly reduces the number of cross-origin contexts which can observe the state event and thus identify the user through backend communication channels.

Requiring a permission does not completely mitigate the cross-origin identification issue but further reduces the number of sites which are able to participate in such an attack.

A new permission informs the user about the permission the page is requesting.

Screenshot of a permission request dialog
Example icon and text for an "idle-detection" permission request.

Rather than expanding the definition of an existing permission, it is clear to users which sites have access to additional capabilities.

Screenshot of Chromium's page information dialog
Example page information dialog box showing a site with both "notifications" and "idle-detection" permissions granted.

This capability changes the web privacy model by allowing the site to observe a limited amount of information about how the user interacts with their device outside the border of the site's content area. Sites using this permission should present the request in a context which explains the value to the user of being granted this capability.

Implementations that provide a "privacy browsing" mode should not enable this capability in such a mode. This may be satisfied incidentally by not allowing notification permission to be granted. Care should be taken to avoid allowing sites to detect this mode by, for example, randomly delaying the automatic disapproval of the notification permission so that it appears to have been denied by the user.

Alternative Permissions Models

Event Timing Fuzzing

The current idle state and the timing of transitions between states are global state which could be used to identify a user across origin boundaries. For example, two cooperating sites could compare the timestamps at which they observed clients transitioning from "active" to "idle". Two clients which appear to consistently make transitions at the same time have a high likelyhood of being the same user.

A mitigation with the potential to directly address this attack is to add a random delay between when the specified threshold is passed and when the "change" event is fired.

This mitigation was considered and determined to be unacceptable because:

  • Delaying the event by even a small amount drastically reduces the usefulness of the API in chat applications which want to ensure that messages are delivered to the correct device.
  • Even with a large fuzzing factor (e.g. 30 seconds) data collected over a long period of time is still sufficient to identify the user.

Combined with Notification Permission

Rather than defining a new "idle-detection" permission, the definition of the existing "notifications" permission could be expanded to control access to this capability. The most compelling use cases for this capability involve messaging applications, so the "notifications" permission seems appropriate.

The advantage of not defining a new permission type is that it helps to avoid "consent fatigue", in which users are presented with an endlessly increasing number of choices by operating systems, browsers, and web sites. Adding this capability to a related permission such as "notifications" can maintain a user's control while reducing the number of decisions that need to be made.

The disadvantage of not defining a new permission is that it changes the meaning of permission decisions the user had made in the past. While notifications are related to signals of user presence the ability to monitor this state may not be something the user considers when granting this permission.

There is a middle-ground in which the permission prompt text for the "notifications" permission is updated to explain this new capability but both capabilities are still controlled by a single permission. Implementations could internally track whether the user has seen the updated prompt and require a site re-request the "notifications" permission before it has access to the new capability.

Prior Work

  • Chrome's chrome.idle API for apps/extensions, which is a direct inspiration for this proposal.
    • Also exposed to Extensions in Firefox MDN
    • And Edge
    • That API has a global (per-execution-context) threshold and one source of events. This makes it difficult for two components on the same page to implement different thresholds.
  • Attempts to do this from JS running on the page:

idle-detection's People

Contributors

anssiko avatar autokagami avatar beaufortfrancois avatar cwilso avatar inexorabletash avatar jpmedley avatar marcoscaceres avatar nidhijaju avatar nschonni avatar reillyeon avatar samuelgoto avatar tabatkins avatar tomayac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

idle-detection's Issues

Migrate into a working group

There is interest within the Devices and Sensors WG for adding this specification to their list of tentative deliverables. This does not mean that work will immediately move into this working group but that a reference to this specification will be added to the working group's charter so that such a migration will be possible at a later date.

As editor of the specification I support this action.

@LJWatson @cwilso @yoavweiss @travisleithead, as chairs of the WICG do you concur?

Not all use cases of this API need the `notifications` permission

One use case of this API could be kiosk setups. Imagine a museum where there are info terminals for visitors. One part of the experience could be a drawing web app for kids. Another part of the experience could be regular info web pages about the exhibition for interested visitors.

Someone might draw inappropriate things in the drawing web app as a "prank" and then multitask to an info web page. The next kid that arrives might find the drawing app in that unfortunate state.

In such cases, it might be desirable for the museum to reset the drawing app after a certain amount of idleness is detected.

This use case happens to be the example I chose for the web.dev article on the API.

Replace stop() with an AbortSignal

It is not currently possible to stop the IdleDetector. An AbortSignal should be added. An option question is whether this should be added as a constructor parameter or a start() parameter.

Define observation behavior when permission is revoked/granted

Cases:

  • permission not granted; event listener added; permission granted - do events start?
  • permission granted; event listener added; permission revoked - do events stop?
  • permission not granted; event listener added; permission granted; permission revoked

Expand explainer

This explainer is good!

I'd like to see a few things expanded on:

  • enumerate non-goals
  • provide an "open design issues" section
  • flesh out the list of prior work to include some of the more popular Node/Electron modules (e.g. node-desktop-idle, the Electron powerMonitor module, etc.)
  • add a "Considered Alternatives" section to discuss tradeoffs and different available API style options
  • expand example code to show how the provided sample code addresses the provided list of use-cases
  • in example code, show how this API will integrate with (and be used around) the Permissions API
  • discuss how this API integrates with existing APIs that provide some info in this area (Page Lifecycle API, Page Visibility API, etc.)
  • outline or discuss integration into worker contexts, specifically Service Workers

New concepts for idle detection

Hi all!

1. feature-name

New concepts for idle detection

2. feature-description

I recently wrote some concepts, sketches, ideas to create an API or a way to find out how the user interacts with the page - reference here. So... I made a code that does what I'm saying and in this evaluation that can be inserted in the proposal here - reference here

3. Why? \Notes

  1. I would like to contribute to this proposal.
  2. I would be happy to help this proposal.
  3. My algorithm is a timer, that is, the way the user uses the page according to a defined time.
    • In addition, all interactions are saved in localstorage. This allows, for example, to have a list of previous interactions. With this, it is possible to verify a pattern of behavior of the same type of user.
    • In addition I created a code snippet that creates a percentage, my idea is to check the quality of user interaction. My goal is to check the level of engagement of user interaction on the page.
    • In my algorithm it is possible to check the time the page takes to load as well.
  4. I would like to unite two ideas in common: User Interact Api and Idle-Detection.

4. Source-code

var start=0, end;
const timeleft = 10;
const TimeExpect = 1;
const TimeExpectWait = 1;
const message= 'The time is over! User Interact Clicking A Button For A Set Time - timeExpect is: '

const UserInteractLocalStorage = (nameDef, value) => {
    localStorage.setItem(nameDef, value);
    return localStorage.getItem(nameDef);
}

const UserWaitForPageToLoad = () => {
    let timePageLoad = window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart
    return UserInteractLocalStorage("timePageLoad", timePageLoad)
}

const UserInteractionForm = () => {
  $('.eform input').on('focus', function(e){
   start=Date.now()
  })
  $(document).on('submit','.eform', function(e){
    end=Date.now()-start;
    let number = start+end;
    console.log("Seconds filling the form", parseFloat(end/1000).toFixed(2) );
    UserInteractLocalStorage("InteractionByForm", number);
});
}

const downloadTimer = setInterval(() => {
  if(timeleft <= 0){
    clearInterval(downloadTimer);
    document.getElementById("countdown").innerHTML = "Finished";
  } else {
    document.getElementById("countdown").innerHTML = timeleft + " seconds remaining";
  }
  timeleft -= 1;
}, 1000);

const progressBar = setInterval( () => {
  if(timeleft <= 0){
    clearInterval(downloadTimer);
  }
  document.getElementById("progressBar").value = 10 - timeleft;
  timeleft -= 1;
}, 1000);

// Timer
// add id Button 
// sample id: '#UserInteractClickingAButtonForASetTime' 
// var button = document.querySelector('button');
// add millisecond|second|minute|hour|day|month|week|year|month|start date|end date|time interval
// add document.getElementById('typeTime').innerText = returnData(typeTime);
// sample document.getElementById('millisecond').innerText = returnData(millisecond); ...etc

function Timer(mins, target, cb) {
    this.counter = mins * 60;
    this.target = target;
    this.callback = cb;
}
Timer.prototype.pad = function(s) {
    return (s < 10) ? '0' + s : s;
}
Timer.prototype.start = function(s) {
    this.count();
}
Timer.prototype.stop = function(s) {
    this.count();
}
Timer.prototype.done = function(s) {
    if (this.callback) this.callback();
}
Timer.prototype.display = function(s) {
    this.target.innerHTML = this.pad(s);
}
Timer.prototype.count = function(s) {
    const self = this;
    self.display.call(self, self.counter);
    self.counter--;
    const clock = setInterval(function() {
        self.display(self.counter);
        self.counter--;
        if (self.counter < 0) {
            clearInterval(clock);
            self.done.call(self);
        }
    }, 1000);
}

const UserInteractButton = (idButton, message, TimeExpect, TimeExpectWait, typeTimeIndex, EngagementLevelIndex) => {
  let button = document.querySelector(idButton)
  let element = document.createElement('div');
  element.setAttribute("id", "viewer");
  element.innerHTML = '';
  document.body.appendChild(element);
  let viewer = document.querySelector('#viewer');
  let getTimer = document.getElementById("viewer").value;
  console.log(getTimer);
  let EngagementLevel = ['new', 'low', 'medium', 'high', 'old']; //window.getDomainEngagementLevel => ‘new’, ‘low’, ‘medium’, ‘high
  let typeTime = ['minutes', 'seconds', 'milliseconds']
  button.addEventListener('click', function() {
    new Timer(TimeExpect, viewer, function() {
        if(TimeExpect==TimeExpectWait){ // timeType: minutes || seconds || milliseconds == TimeExpectWait
          console.log(message+TimeExpect+' '+typeTime[typeTimeIndex], 'EngagementLevel'+EngagementLevel[EngagementLevelIndex]);
          UserInteractLocalStorage('UserInteractButton', TimeExpectWait);
        }
    }).start();
});
}

// UserInteractButton('#UserInteractClickingAButtonForASetTime', message, TimeExpect, TimeExpectWait, 0, 1);
// UserInteractButton('#UserInteractClickingAButtonForASetTime', message, TimeExpect, TimeExpectWait, 0, 2);
// UserInteractButtonn('#UserInteractClickingAButtonForASetTime', message, TimeExpect, TimeExpectWait, 0, 3);
// UserInteractButton('#UserInteractClickingAButtonForASetTime', message, TimeExpect, TimeExpectWait, 0, 4);
// UserInteractButton('#UserInteractClickingAButtonForASetTime', message, UserWaitForPageToLoad(), TimeExpectWait, 0, 4);
UserInteractButton('#UserInteractClickingAButtonForASetTime', message, TimeExpect, TimeExpectWait, 0, 0);

5. References

Observer Instead of Detector/Start/Abort

They way this API is presented is confusing.

An IdleDetector object is understandable but then using start is non-standard and outside of what most developers think of. Then, instead of doing IdleDetector.stop() it requires the use of a signal that uses AbortController which makes no sense. In a fetch request, the AbortController is uses to abort or stop fetching a resource. In this context it, and upon first reading the spec, I thought it was a way to prevent the user from going idle (like preventing screen saver). It was confusing to think that abort was the way to stop watching for an idle user.

Instead, I propose going the Intersection Observer API route since it is not confusing to think that you are observing when a user is or is not idle.

if ((await navigator.permissions.query({name: 'notifications'})).state !== 'granted') {
    console.log('Notifications permission not granted.');
    // Request permission
}

if ((await navigator.permissions.query({name: 'notifications'})).state == 'granted')
    var idleObs = new UserIdleObserver((states, observer) => {
        // states.user UserIdleState
        // states.screen ScreenIdleState
    }, { threshold: 60000 });

    idleObs.observe();

    // Done observing?
    window.setTimeout(() => {
        idleObs.unobserve();
    }, 120000);
}

Where the observe() can either contain no parameters or one (the global object). No parameter defaults to the global object.

At the very least I don't feel using AbortController is necessary (at least externally) and is confusing.

const idleDetector = new IdleDetector();
idleDetector.addEventListener('change', () => {
  console.log(`Idle change: ${idleDetector.userState}, ${idleDetector.screenState}.`);
});    
await idleDetector.start({
  threshold: 60000,
});
window.setTimeout(() => {
  await idleDetector.stop();
  console.log('IdleDetector is stopped.');
}, 120000);

Idle Detection API to avoid spam in mails?

Introduction

The Idle Detection API notifies developers when a user is idle, indicating such things as lack of interaction with the keyboard, mouse, screen, activation of a screensaver, locking of the screen, or moving to a different screen. A developer-defined threshold triggers the notification.

Motivation

I would like to know if it would be possible to use IddleDetector to check if certain behavior of certain users is malicious or considered as spam. Applications such as email that facilitate collaboration or communication must require more global signals about whether the user is idle than those provided by existing mechanisms that only consider user interaction with the application tab itself. Because one of the current problems with email is spam. Usually, the spam is rarely sent directly by a company advertising itself. It's usually sent by a "spammer," a company in the business of distributing unsolicited email. An advertiser enters into an agreement with a spammer, who generates email advertisements to a group of unsuspecting recipients. And because maybe this is an alternative to the captcha thing in a way, because it's based on behavior.

Solution

There are several security tips to avoid email spam which include:

  • Never give out or post your email address publicly
  • Think before you click
  • Do not reply to spam messages
  • Download spam filtering tools and anti-virus software
  • Avoid using your personal or business email address

But the advantage of this: "Idle Detection API to avoid spam in mails" is that the system itself could denounce or report certain users who have strange, malicious behavior or even spammers. Another initial advantage is that it works on the client side and not on the server side (this is because it avoids some processing expense.)

what do you think of this idea?

Privacy section: Exposing that the user is active may be undesirable

One of the use cases listed is a chat application that show's the users online status.

I suggest the privacy section might want to discuss whether this is desirable or not. A user may deliberately avoid opening a chat application until they are ready to interact with a particular acquaintance. I think most users would assume that their acquaintance sees them as offline until that they open the app again (I believe this is how Messenger works). If their online status is revealed they may feel their privacy has been undermined and it could be awkward or even become a vector for stalking.

Relationship to focus

Probably want to add a little bit in the readme about how this is also different from window focus events.

Should we pass parameters to the event listener and drop the per instance state?

Right now, our API is such that you get the state out of the detector, and you listen for "change" events to observe changes.

let idleDetector = new IdleDetector({ threshold: 60 });
idleDetector.addEventListener('change', () => {
  // we get the state from the idle detector instance
  let {user, scree} = idleDetector.state;
  console.log(`idle change: ${user}, ${screen}`);
});
idleDetector.start();

We should probably drop the "state" property of IdleDetector and pass it on the event listener as a parameter, e.g.:

let idleDetector = new IdleDetector({threshold: 60});
idleDetector.addEventListener('change', ({user, screen}) => {
  // the state is passed as a parameter to the event listener.
  // idleDetector.state == undefined.
  console.log(`idle change: ${user}, ${screen}`);
});
idleDetector.start();

Not entirely consistent with the sensors API [1], but the "reading" in the sensors API doesn't seem like the best analogy either.

@ReillyG, does that make sense? any other supporting precendence here?

[1] https://developer.mozilla.org/en-US/docs/Web/API/Accelerometer

API shape - modernize the API

There are several problems with the chrome.idle.* API shape:

  1. it requires all code running within a context (e.g. window) to share the same idle threshold. This could be problematic for multiple libraries / widgets on the same page
  2. when using the event, there's no obvious place to hang a permission request, which is usually done on a method call.
  3. doing a query() and registering an event listener can race - it would be possible for both to return the same result or different results. Ideally you'd get a known state and change sequences relative to that.

Here's a proposal based on the shape in the Permissions API which addresses all three issues:

const status = await navigator.idle.query({threshold: 10}); // threshold is per query (#1)
// permission prompt here, if necessary (#2)
console.log(status.state); // current status
status.addEventListener('change', e => {
  console.log(status.state); // update changes the status object (#3)
});

Question: Support for IdleDetector interface exposure to ServiceWorker?

Hello!

I note that the current interface declares that IdleDetector is only exposed to Window and DedicatedWorker. Is there any consideration for exposing the IdleDetector interface to ServiceWorker? Possible use cases where this would provide value:

  • An application that signals the user via Notifications via a service worker can detect user idle state, and thus redirect notifications to other devices.
  • An application that relies on active user presence (per NIST 800-63B reauthentication requirements) could utilize this to poll for user presence and signal a corresponding server-side component as to keep a user session alive, even where the user navigates away to other applications.

Thank you.

Idle Detection API should allow for limiting to an origin

"[The Idle Detection API] should support customizing the detection scheme. It should also allow to just specify "detect if user has the tab focused, and is interacting with the document". In that scenario it shouldn't prompt (there's no privacy concern because you can already implement that on your own). It should definitely keep prompting for what it does right now: detecting idle state across tabs & OS apps — not only that, it should explicitly say in the prompt that it'll do this (which I didn't know about when I read it at first)."—via @dwelle on excalidraw/excalidraw#2877 (comment) in excalidraw/excalidraw#2877.

This could look like the following snippet and would only cover tabs opened to the mentioned origin and thus not report on activity in other non-browser apps or non-related tabs, and likewise allow for no assumptions about the screenState—and due to its reduced powers not require permissions, since the same can be implemented client-side today.

const controller = new AbortController();
const signal = controller.signal;
const idleDetector = new IdleDetector();
idleDetector.start({
  threshold: 60_000,
  signal: signal,
  origin: 'example.com', // 🆕
});

Remove IdleState interface

The IdleState interface does not seem necessary. Two alternatives:

  1. Make IdleState a dictionary.
  2. Add the fields of IdleState directly to IdleDetector.

The disadvantage of (1) is that interface members should not be dictionaries and so a new getState() method should be added. This adds additional overhead. I prefer option (2).

Allow implicit permission grants?

The permission can be explicitly requested via navigator.permissions. Should we allow calls to query() (etc) to implicitly request the permission as well? If so, how does the query resolve if the permission is denied?

[feedback] [public commentary] How does this benefit USERS?

Lots of reasons why/how this could benefit developers -- especially developers who participate in the surveillance-economy -- but zero explanation about how this could benefit regular users.

As a user, I certainly do not want my hardware (keyboard, mouse), or any other out-of-context status reported to or detectable by a some bit of injected js.

If this is to be established as a standard, the question of how it benefits users and not just developers and site hosts, must be answered.

  1. What risks of abuse does this create? (I can think of dozens. Can you?)
  2. How are those risks mitigated in code?
  3. What benefit is provide to a site or web-application's users?
  4. What alternative means of providing [benefit] already exist?
  5. How does this improve upon prior art?
  6. In what ways is this inferior to prior art?

Some questions beyond the explainer

Hi

I have a large list of notification permissions granted to websites and PWA's that I normally receive reports from.

I wonder how this API will work for these established cases. It was not for this purpose (whether or not I am interacting on my computer) that I granted permissions.

How will users be informed by the UI of the permissions api about the possibility of this "monitoring" (if any intention for display this info)?

The current Notification API request model is "intuitive" to the user. The user grants permission in the expectation of receiving notifications only.

From the user's point of view how would he be informed that the application could know or determine whether or not he is interacting on his device even away from the application/website?

I understand the legitimate use cases, but shouldn't the user know and be able to choose to grant this information (the state)?

I don't have much to say about the plugins mentioned in the inspiration examples, but when a user installs a plugin he is informed about what that plugin does and it can be said that he is already aware of it.

I am more concerned with the call that this proposal uses, an already established banner (Notifications) that users are already used to doing something different from this purpose.

Avoid global?

It might make as much (or more) sense to view this at a promise-returning API; e.g.:

async function main() {
  // feature detection.
  if (!navigator.idle) {
    console.log("Idle detection is not available :(");
    return;
  }
  
  console.log("Idle detection is available! Go idle!");
  
  try {
    await detector = navigator.idle.request({ threshold: 60 });
    // maybe we can implicitly start here? Is there a good reason not to?
    detector.addEventListener('change', ({user, screen}) => { 
      console.log(`idle change: ${user}, ${screen}`);
    });
  } catch (e) {
    // deal with initialization errors.
    // permission denied, running outside of top-level frame, etc
  }
};

Time-based correlation

Two origins with 'idle-detection' permission will receive an event at approximately the same time. This allows an adversary with access to both origins the ability to identify the two as being the same browser with high probability. This was the basis of the attacks on the battery status API.

This is not mentioned in #29, but probably should be. The usual defenses we deploy here is to defer the event until the window gains focus, which is not going to work in this case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.