mirror of
https://github.com/denoland/deno.git
synced 2024-11-22 15:06:54 -05:00
Revert "feat: move unstable Deno.permissions to navigator.permissions… (#6729)
* Revert "feat: move unstable Deno.permissions to navigator.permissions (#6244)"
This reverts commit 202e7fa6ad
.
This commit is contained in:
parent
44187c81f4
commit
11560387bb
15 changed files with 236 additions and 396 deletions
|
@ -19,6 +19,9 @@ export { shutdown, ShutdownMode } from "./net.ts";
|
||||||
export { listen, listenDatagram, connect } from "./net_unstable.ts";
|
export { listen, listenDatagram, connect } from "./net_unstable.ts";
|
||||||
export { startTls } from "./tls.ts";
|
export { startTls } from "./tls.ts";
|
||||||
export { kill } from "./ops/process.ts";
|
export { kill } from "./ops/process.ts";
|
||||||
|
export { permissions, Permissions } from "./permissions.ts";
|
||||||
|
export { PermissionStatus } from "./permissions.ts";
|
||||||
|
export type { PermissionName, PermissionState } from "./permissions.ts";
|
||||||
export { DiagnosticCategory } from "./diagnostics.ts";
|
export { DiagnosticCategory } from "./diagnostics.ts";
|
||||||
export type {
|
export type {
|
||||||
Diagnostic,
|
Diagnostic,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import * as abortSignal from "./web/abort_signal.ts";
|
||||||
import * as blob from "./web/blob.ts";
|
import * as blob from "./web/blob.ts";
|
||||||
import * as consoleTypes from "./web/console.ts";
|
import * as consoleTypes from "./web/console.ts";
|
||||||
import * as csprng from "./ops/get_random_values.ts";
|
import * as csprng from "./ops/get_random_values.ts";
|
||||||
|
import type * as promiseTypes from "./web/promise.ts";
|
||||||
import * as customEvent from "./web/custom_event.ts";
|
import * as customEvent from "./web/custom_event.ts";
|
||||||
import * as domException from "./web/dom_exception.ts";
|
import * as domException from "./web/dom_exception.ts";
|
||||||
import * as domFile from "./web/dom_file.ts";
|
import * as domFile from "./web/dom_file.ts";
|
||||||
|
@ -16,19 +17,16 @@ import * as eventTarget from "./web/event_target.ts";
|
||||||
import * as formData from "./web/form_data.ts";
|
import * as formData from "./web/form_data.ts";
|
||||||
import * as fetchTypes from "./web/fetch.ts";
|
import * as fetchTypes from "./web/fetch.ts";
|
||||||
import * as headers from "./web/headers.ts";
|
import * as headers from "./web/headers.ts";
|
||||||
import * as navigator from "./web/navigator.ts";
|
|
||||||
import * as permissions from "./web/permissions.ts";
|
|
||||||
import type * as promiseTypes from "./web/promise.ts";
|
|
||||||
import * as queuingStrategy from "./web/streams/queuing_strategy.ts";
|
|
||||||
import * as readableStream from "./web/streams/readable_stream.ts";
|
|
||||||
import * as request from "./web/request.ts";
|
|
||||||
import * as textEncoding from "./web/text_encoding.ts";
|
import * as textEncoding from "./web/text_encoding.ts";
|
||||||
import * as timers from "./web/timers.ts";
|
import * as timers from "./web/timers.ts";
|
||||||
import * as transformStream from "./web/streams/transform_stream.ts";
|
|
||||||
import * as url from "./web/url.ts";
|
import * as url from "./web/url.ts";
|
||||||
import * as urlSearchParams from "./web/url_search_params.ts";
|
import * as urlSearchParams from "./web/url_search_params.ts";
|
||||||
import * as workers from "./web/workers.ts";
|
import * as workers from "./web/workers.ts";
|
||||||
import * as performance from "./web/performance.ts";
|
import * as performance from "./web/performance.ts";
|
||||||
|
import * as request from "./web/request.ts";
|
||||||
|
import * as readableStream from "./web/streams/readable_stream.ts";
|
||||||
|
import * as transformStream from "./web/streams/transform_stream.ts";
|
||||||
|
import * as queuingStrategy from "./web/streams/queuing_strategy.ts";
|
||||||
import * as writableStream from "./web/streams/writable_stream.ts";
|
import * as writableStream from "./web/streams/writable_stream.ts";
|
||||||
|
|
||||||
// These imports are not exposed and therefore are fine to just import the
|
// These imports are not exposed and therefore are fine to just import the
|
||||||
|
@ -223,19 +221,15 @@ export const windowOrWorkerGlobalScopeProperties = {
|
||||||
queuingStrategy.ByteLengthQueuingStrategyImpl
|
queuingStrategy.ByteLengthQueuingStrategyImpl
|
||||||
),
|
),
|
||||||
CountQueuingStrategy: nonEnumerable(queuingStrategy.CountQueuingStrategyImpl),
|
CountQueuingStrategy: nonEnumerable(queuingStrategy.CountQueuingStrategyImpl),
|
||||||
CustomEvent: nonEnumerable(customEvent.CustomEventImpl),
|
|
||||||
crypto: readOnly(csprng),
|
crypto: readOnly(csprng),
|
||||||
|
File: nonEnumerable(domFile.DomFileImpl),
|
||||||
|
CustomEvent: nonEnumerable(customEvent.CustomEventImpl),
|
||||||
DOMException: nonEnumerable(domException.DOMExceptionImpl),
|
DOMException: nonEnumerable(domException.DOMExceptionImpl),
|
||||||
ErrorEvent: nonEnumerable(errorEvent.ErrorEventImpl),
|
ErrorEvent: nonEnumerable(errorEvent.ErrorEventImpl),
|
||||||
Event: nonEnumerable(event.EventImpl),
|
Event: nonEnumerable(event.EventImpl),
|
||||||
EventTarget: nonEnumerable(eventTarget.EventTargetImpl),
|
EventTarget: nonEnumerable(eventTarget.EventTargetImpl),
|
||||||
File: nonEnumerable(domFile.DomFileImpl),
|
|
||||||
FormData: nonEnumerable(formData.FormDataImpl),
|
|
||||||
Headers: nonEnumerable(headers.HeadersImpl),
|
Headers: nonEnumerable(headers.HeadersImpl),
|
||||||
navigator: nonEnumerable(new navigator.NavigatorImpl()),
|
FormData: nonEnumerable(formData.FormDataImpl),
|
||||||
Navigator: nonEnumerable(navigator.NavigatorImpl),
|
|
||||||
Permissions: nonEnumerable(permissions.PermissionsImpl),
|
|
||||||
PermissionStatus: nonEnumerable(permissions.PermissionStatusImpl),
|
|
||||||
ReadableStream: nonEnumerable(readableStream.ReadableStreamImpl),
|
ReadableStream: nonEnumerable(readableStream.ReadableStreamImpl),
|
||||||
Request: nonEnumerable(request.Request),
|
Request: nonEnumerable(request.Request),
|
||||||
Response: nonEnumerable(fetchTypes.Response),
|
Response: nonEnumerable(fetchTypes.Response),
|
||||||
|
|
93
cli/js/lib.deno.ns.d.ts
vendored
93
cli/js/lib.deno.ns.d.ts
vendored
|
@ -63,40 +63,6 @@ declare interface PerformanceMeasureOptions {
|
||||||
end?: string | number;
|
end?: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface Permissions {
|
|
||||||
/** Resolves to the current status of a permission.
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* const status = await navigator.permissions.query({ name: "read", path: "/etc" });
|
|
||||||
* if (status.state === "granted") {
|
|
||||||
* data = await Deno.readFile("/etc/passwd");
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
query(permissionDesc: Deno.PermissionDescriptor): Promise<PermissionStatus>;
|
|
||||||
|
|
||||||
/** Requests the permission, and resolves to the state of the permission.
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* const status = await navigator.permissions.request({ name: "env" });
|
|
||||||
* if (status.state === "granted") {
|
|
||||||
* console.log(Deno.dir("home");
|
|
||||||
* } else {
|
|
||||||
* console.log("'env' permission is denied.");
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
request(permissionDesc: Deno.PermissionDescriptor): Promise<PermissionStatus>;
|
|
||||||
|
|
||||||
/** Revokes a permission, and resolves to the state of the permission.
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* const status = await Deno.revoke({ name: "run" });
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
revoke(permissionDesc: Deno.PermissionDescriptor): Promise<PermissionStatus>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare namespace Deno {
|
declare namespace Deno {
|
||||||
/** A set of error constructors that are raised by Deno APIs. */
|
/** A set of error constructors that are raised by Deno APIs. */
|
||||||
export const errors: {
|
export const errors: {
|
||||||
|
@ -1977,65 +1943,6 @@ declare namespace Deno {
|
||||||
* Requires `allow-run` permission. */
|
* Requires `allow-run` permission. */
|
||||||
export function run<T extends RunOptions = RunOptions>(opt: T): Process<T>;
|
export function run<T extends RunOptions = RunOptions>(opt: T): Process<T>;
|
||||||
|
|
||||||
/** The name of a "powerful feature" which needs permission.
|
|
||||||
*
|
|
||||||
* See: https://w3c.github.io/permissions/#permission-registry
|
|
||||||
*
|
|
||||||
* Note that the definition of `PermissionName` in the above spec is swapped
|
|
||||||
* out for a set of Deno permissions which are not web-compatible. */
|
|
||||||
export type PermissionName =
|
|
||||||
| "run"
|
|
||||||
| "read"
|
|
||||||
| "write"
|
|
||||||
| "net"
|
|
||||||
| "env"
|
|
||||||
| "plugin"
|
|
||||||
| "hrtime";
|
|
||||||
|
|
||||||
export interface RunPermissionDescriptor {
|
|
||||||
name: "run";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReadPermissionDescriptor {
|
|
||||||
name: "read";
|
|
||||||
path?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WritePermissionDescriptor {
|
|
||||||
name: "write";
|
|
||||||
path?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NetPermissionDescriptor {
|
|
||||||
name: "net";
|
|
||||||
url?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EnvPermissionDescriptor {
|
|
||||||
name: "env";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PluginPermissionDescriptor {
|
|
||||||
name: "plugin";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrtimePermissionDescriptor {
|
|
||||||
name: "hrtime";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Permission descriptors which define a permission and can be queried,
|
|
||||||
* requested, or revoked.
|
|
||||||
*
|
|
||||||
* See: https://w3c.github.io/permissions/#permission-descriptor */
|
|
||||||
export type PermissionDescriptor =
|
|
||||||
| RunPermissionDescriptor
|
|
||||||
| ReadPermissionDescriptor
|
|
||||||
| WritePermissionDescriptor
|
|
||||||
| NetPermissionDescriptor
|
|
||||||
| EnvPermissionDescriptor
|
|
||||||
| PluginPermissionDescriptor
|
|
||||||
| HrtimePermissionDescriptor;
|
|
||||||
|
|
||||||
export interface InspectOptions {
|
export interface InspectOptions {
|
||||||
/** Traversal depth for nested objects. Defaults to 4. */
|
/** Traversal depth for nested objects. Defaults to 4. */
|
||||||
depth?: number;
|
depth?: number;
|
||||||
|
|
54
cli/js/lib.deno.shared_globals.d.ts
vendored
54
cli/js/lib.deno.shared_globals.d.ts
vendored
|
@ -1646,60 +1646,6 @@ declare const AbortSignal: {
|
||||||
new (): AbortSignal;
|
new (): AbortSignal;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PermissionState = "denied" | "granted" | "prompt";
|
|
||||||
|
|
||||||
interface PermissionStatusEventMap {
|
|
||||||
change: Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PermissionStatus extends EventTarget {
|
|
||||||
onchange: ((this: PermissionStatus, ev: Event) => any) | null;
|
|
||||||
readonly state: PermissionState;
|
|
||||||
addEventListener<K extends keyof PermissionStatusEventMap>(
|
|
||||||
type: K,
|
|
||||||
listener: (this: PermissionStatus, ev: PermissionStatusEventMap[K]) => any,
|
|
||||||
options?: boolean | AddEventListenerOptions
|
|
||||||
): void;
|
|
||||||
addEventListener(
|
|
||||||
type: string,
|
|
||||||
listener: EventListenerOrEventListenerObject,
|
|
||||||
options?: boolean | AddEventListenerOptions
|
|
||||||
): void;
|
|
||||||
removeEventListener<K extends keyof PermissionStatusEventMap>(
|
|
||||||
type: K,
|
|
||||||
listener: (this: PermissionStatus, ev: PermissionStatusEventMap[K]) => any,
|
|
||||||
options?: boolean | EventListenerOptions
|
|
||||||
): void;
|
|
||||||
removeEventListener(
|
|
||||||
type: string,
|
|
||||||
listener: EventListenerOrEventListenerObject,
|
|
||||||
options?: boolean | EventListenerOptions
|
|
||||||
): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Deno does not currently support any of the browser permissions, and so the
|
|
||||||
* `name` property of the global types is `undefined`. The Deno permissions
|
|
||||||
* that are supported are defined in the `lib.deno.ns.d.ts` and pull from the
|
|
||||||
* `Deno` namespace. */
|
|
||||||
declare interface PermissionDescriptor {
|
|
||||||
name: undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface Permissions {
|
|
||||||
query(permissionDesc: PermissionDescriptor): Promise<PermissionStatus>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare const Permissions: {
|
|
||||||
prototype: Permissions;
|
|
||||||
new (): Permissions;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare class Navigator {
|
|
||||||
readonly permissions: Permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare const navigator: Navigator;
|
|
||||||
|
|
||||||
interface ErrorConstructor {
|
interface ErrorConstructor {
|
||||||
/** See https://v8.dev/docs/stack-trace-api#stack-trace-collection-for-custom-exceptions. */
|
/** See https://v8.dev/docs/stack-trace-api#stack-trace-collection-for-custom-exceptions. */
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
|
114
cli/js/lib.deno.unstable.d.ts
vendored
114
cli/js/lib.deno.unstable.d.ts
vendored
|
@ -971,6 +971,120 @@ declare namespace Deno {
|
||||||
* Requires `allow-run` permission. */
|
* Requires `allow-run` permission. */
|
||||||
export function kill(pid: number, signo: number): void;
|
export function kill(pid: number, signo: number): void;
|
||||||
|
|
||||||
|
/** The name of a "powerful feature" which needs permission.
|
||||||
|
*
|
||||||
|
* See: https://w3c.github.io/permissions/#permission-registry
|
||||||
|
*
|
||||||
|
* Note that the definition of `PermissionName` in the above spec is swapped
|
||||||
|
* out for a set of Deno permissions which are not web-compatible. */
|
||||||
|
export type PermissionName =
|
||||||
|
| "run"
|
||||||
|
| "read"
|
||||||
|
| "write"
|
||||||
|
| "net"
|
||||||
|
| "env"
|
||||||
|
| "plugin"
|
||||||
|
| "hrtime";
|
||||||
|
|
||||||
|
/** The current status of the permission.
|
||||||
|
*
|
||||||
|
* See: https://w3c.github.io/permissions/#status-of-a-permission */
|
||||||
|
export type PermissionState = "granted" | "denied" | "prompt";
|
||||||
|
|
||||||
|
export interface RunPermissionDescriptor {
|
||||||
|
name: "run";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReadPermissionDescriptor {
|
||||||
|
name: "read";
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WritePermissionDescriptor {
|
||||||
|
name: "write";
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NetPermissionDescriptor {
|
||||||
|
name: "net";
|
||||||
|
/** Optional url associated with this descriptor.
|
||||||
|
*
|
||||||
|
* If specified: must be a valid url. Expected format: <scheme>://<host_or_ip>[:port][/path]
|
||||||
|
* If the scheme is unknown, callers should specify some scheme, such as x:// na:// unknown://
|
||||||
|
*
|
||||||
|
* See: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml */
|
||||||
|
url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnvPermissionDescriptor {
|
||||||
|
name: "env";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PluginPermissionDescriptor {
|
||||||
|
name: "plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HrtimePermissionDescriptor {
|
||||||
|
name: "hrtime";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Permission descriptors which define a permission and can be queried,
|
||||||
|
* requested, or revoked.
|
||||||
|
*
|
||||||
|
* See: https://w3c.github.io/permissions/#permission-descriptor */
|
||||||
|
export type PermissionDescriptor =
|
||||||
|
| RunPermissionDescriptor
|
||||||
|
| ReadPermissionDescriptor
|
||||||
|
| WritePermissionDescriptor
|
||||||
|
| NetPermissionDescriptor
|
||||||
|
| EnvPermissionDescriptor
|
||||||
|
| PluginPermissionDescriptor
|
||||||
|
| HrtimePermissionDescriptor;
|
||||||
|
|
||||||
|
export class Permissions {
|
||||||
|
/** Resolves to the current status of a permission.
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const status = await Deno.permissions.query({ name: "read", path: "/etc" });
|
||||||
|
* if (status.state === "granted") {
|
||||||
|
* data = await Deno.readFile("/etc/passwd");
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
query(desc: PermissionDescriptor): Promise<PermissionStatus>;
|
||||||
|
|
||||||
|
/** Revokes a permission, and resolves to the state of the permission.
|
||||||
|
*
|
||||||
|
* const status = await Deno.permissions.revoke({ name: "run" });
|
||||||
|
* assert(status.state !== "granted")
|
||||||
|
*/
|
||||||
|
revoke(desc: PermissionDescriptor): Promise<PermissionStatus>;
|
||||||
|
|
||||||
|
/** Requests the permission, and resolves to the state of the permission.
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const status = await Deno.permissions.request({ name: "env" });
|
||||||
|
* if (status.state === "granted") {
|
||||||
|
* console.log(Deno.dir("home");
|
||||||
|
* } else {
|
||||||
|
* console.log("'env' permission is denied.");
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
request(desc: PermissionDescriptor): Promise<PermissionStatus>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** **UNSTABLE**: Under consideration to move to `navigator.permissions` to
|
||||||
|
* match web API. It could look like `navigator.permissions.query({ name: Deno.symbols.read })`.
|
||||||
|
*/
|
||||||
|
export const permissions: Permissions;
|
||||||
|
|
||||||
|
/** see: https://w3c.github.io/permissions/#permissionstatus */
|
||||||
|
export class PermissionStatus {
|
||||||
|
state: PermissionState;
|
||||||
|
constructor(state: PermissionState);
|
||||||
|
}
|
||||||
|
|
||||||
/** **UNSTABLE**: New API, yet to be vetted. Additional consideration is still
|
/** **UNSTABLE**: New API, yet to be vetted. Additional consideration is still
|
||||||
* necessary around the permissions required.
|
* necessary around the permissions required.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
import { sendSync } from "./dispatch_json.ts";
|
import { sendSync } from "./dispatch_json.ts";
|
||||||
|
import type { PermissionState } from "../permissions.ts";
|
||||||
|
|
||||||
interface PermissionRequest {
|
interface PermissionRequest {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
79
cli/js/permissions.ts
Normal file
79
cli/js/permissions.ts
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
import * as permissionsOps from "./ops/permissions.ts";
|
||||||
|
|
||||||
|
export type PermissionName =
|
||||||
|
| "read"
|
||||||
|
| "write"
|
||||||
|
| "net"
|
||||||
|
| "env"
|
||||||
|
| "run"
|
||||||
|
| "plugin"
|
||||||
|
| "hrtime";
|
||||||
|
// NOTE: Keep in sync with cli/permissions.rs
|
||||||
|
|
||||||
|
export type PermissionState = "granted" | "denied" | "prompt";
|
||||||
|
|
||||||
|
export interface RunPermissionDescriptor {
|
||||||
|
name: "run";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReadPermissionDescriptor {
|
||||||
|
name: "read";
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WritePermissionDescriptor {
|
||||||
|
name: "write";
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NetPermissionDescriptor {
|
||||||
|
name: "net";
|
||||||
|
url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnvPermissionDescriptor {
|
||||||
|
name: "env";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PluginPermissionDescriptor {
|
||||||
|
name: "plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HrtimePermissionDescriptor {
|
||||||
|
name: "hrtime";
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PermissionDescriptor =
|
||||||
|
| RunPermissionDescriptor
|
||||||
|
| ReadPermissionDescriptor
|
||||||
|
| WritePermissionDescriptor
|
||||||
|
| NetPermissionDescriptor
|
||||||
|
| EnvPermissionDescriptor
|
||||||
|
| PluginPermissionDescriptor
|
||||||
|
| HrtimePermissionDescriptor;
|
||||||
|
|
||||||
|
export class PermissionStatus {
|
||||||
|
constructor(public state: PermissionState) {}
|
||||||
|
// TODO(kt3k): implement onchange handler
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Permissions {
|
||||||
|
query(desc: PermissionDescriptor): Promise<PermissionStatus> {
|
||||||
|
const state = permissionsOps.query(desc);
|
||||||
|
return Promise.resolve(new PermissionStatus(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
revoke(desc: PermissionDescriptor): Promise<PermissionStatus> {
|
||||||
|
const state = permissionsOps.revoke(desc);
|
||||||
|
return Promise.resolve(new PermissionStatus(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
request(desc: PermissionDescriptor): Promise<PermissionStatus> {
|
||||||
|
const state = permissionsOps.request(desc);
|
||||||
|
return Promise.resolve(new PermissionStatus(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const permissions = new Permissions();
|
|
@ -1,12 +0,0 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
|
||||||
|
|
||||||
import { PermissionsImpl as Permissions } from "./permissions.ts";
|
|
||||||
|
|
||||||
export class NavigatorImpl implements Navigator {
|
|
||||||
permissions = new Permissions();
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.defineProperty(NavigatorImpl, "name", {
|
|
||||||
value: "Navigator",
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
|
@ -1,181 +0,0 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
|
||||||
|
|
||||||
import * as permissionsOps from "../ops/permissions.ts";
|
|
||||||
import { EventTargetImpl as EventTarget } from "./event_target.ts";
|
|
||||||
|
|
||||||
const permissionNames = [
|
|
||||||
"read",
|
|
||||||
"write",
|
|
||||||
"net",
|
|
||||||
"env",
|
|
||||||
"run",
|
|
||||||
"plugin",
|
|
||||||
"hrtime",
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
type PermissionName = typeof permissionNames[number];
|
|
||||||
|
|
||||||
interface RunPermissionDescriptor {
|
|
||||||
name: "run";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ReadPermissionDescriptor {
|
|
||||||
name: "read";
|
|
||||||
path?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface WritePermissionDescriptor {
|
|
||||||
name: "write";
|
|
||||||
path?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface NetPermissionDescriptor {
|
|
||||||
name: "net";
|
|
||||||
url?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EnvPermissionDescriptor {
|
|
||||||
name: "env";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PluginPermissionDescriptor {
|
|
||||||
name: "plugin";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HrtimePermissionDescriptor {
|
|
||||||
name: "hrtime";
|
|
||||||
}
|
|
||||||
|
|
||||||
type DenoPermissionDescriptor =
|
|
||||||
| RunPermissionDescriptor
|
|
||||||
| ReadPermissionDescriptor
|
|
||||||
| WritePermissionDescriptor
|
|
||||||
| NetPermissionDescriptor
|
|
||||||
| EnvPermissionDescriptor
|
|
||||||
| PluginPermissionDescriptor
|
|
||||||
| HrtimePermissionDescriptor;
|
|
||||||
|
|
||||||
interface StatusCacheValue {
|
|
||||||
state: PermissionState;
|
|
||||||
status: PermissionStatusImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PermissionStatusImpl extends EventTarget
|
|
||||||
implements PermissionStatus {
|
|
||||||
#state: { state: PermissionState };
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
onchange: ((this: PermissionStatus, event: Event) => any) | null = null;
|
|
||||||
|
|
||||||
get state(): PermissionState {
|
|
||||||
return this.#state.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(state: { state: PermissionState }) {
|
|
||||||
super();
|
|
||||||
this.#state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatchEvent(event: Event): boolean {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
let dispatched = super.dispatchEvent(event as any);
|
|
||||||
if (dispatched && this.onchange) {
|
|
||||||
this.onchange.call(this, event);
|
|
||||||
dispatched = !event.defaultPrevented;
|
|
||||||
}
|
|
||||||
return dispatched;
|
|
||||||
}
|
|
||||||
|
|
||||||
get [Symbol.toStringTag](): string {
|
|
||||||
return "PermissionStatus";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A cache of `PermissionStatus` objects and their last known state. */
|
|
||||||
const statusCache = new Map<string, StatusCacheValue>();
|
|
||||||
|
|
||||||
/** Cache the state of a descriptor and return its `PermissionStatus`. */
|
|
||||||
function cache(
|
|
||||||
desc: DenoPermissionDescriptor,
|
|
||||||
state: PermissionState
|
|
||||||
): PermissionStatusImpl {
|
|
||||||
let key = desc.name;
|
|
||||||
if ((desc.name === "read" || desc.name === "write") && desc.path) {
|
|
||||||
key += `-${desc.path}`;
|
|
||||||
} else if (desc.name === "net" && desc.url) {
|
|
||||||
key += `-${desc.url}`;
|
|
||||||
}
|
|
||||||
if (statusCache.has(key)) {
|
|
||||||
const status = statusCache.get(key)!;
|
|
||||||
if (status.state !== state) {
|
|
||||||
status.state = state;
|
|
||||||
status.status.dispatchEvent(new Event("change", { cancelable: false }));
|
|
||||||
}
|
|
||||||
return status.status;
|
|
||||||
}
|
|
||||||
const status: { state: PermissionState; status?: PermissionStatusImpl } = {
|
|
||||||
state,
|
|
||||||
};
|
|
||||||
status.status = new PermissionStatusImpl(status);
|
|
||||||
statusCache.set(key, status as StatusCacheValue);
|
|
||||||
return status.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isValidDescriptor(
|
|
||||||
desc: PermissionDescriptor | DenoPermissionDescriptor
|
|
||||||
): desc is DenoPermissionDescriptor {
|
|
||||||
return permissionNames.includes(desc.name as PermissionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PermissionsImpl implements Permissions {
|
|
||||||
query(
|
|
||||||
desc: PermissionDescriptor | DenoPermissionDescriptor
|
|
||||||
): Promise<PermissionStatus> {
|
|
||||||
if (!isValidDescriptor(desc)) {
|
|
||||||
return Promise.reject(
|
|
||||||
new TypeError(
|
|
||||||
`The provided value "${desc.name}" is not a valid permission name.`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const state = permissionsOps.query(desc);
|
|
||||||
return Promise.resolve(cache(desc, state) as PermissionStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
revoke(
|
|
||||||
desc: PermissionDescriptor | DenoPermissionDescriptor
|
|
||||||
): Promise<PermissionStatus> {
|
|
||||||
if (!isValidDescriptor(desc)) {
|
|
||||||
return Promise.reject(
|
|
||||||
new TypeError(
|
|
||||||
`The provided value "${desc.name}" is not a valid permission name.`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const state = permissionsOps.revoke(desc);
|
|
||||||
return Promise.resolve(cache(desc, state) as PermissionStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
request(
|
|
||||||
desc: PermissionDescriptor | DenoPermissionDescriptor
|
|
||||||
): Promise<PermissionStatus> {
|
|
||||||
if (!isValidDescriptor(desc)) {
|
|
||||||
return Promise.reject(
|
|
||||||
new TypeError(
|
|
||||||
`The provided value "${desc.name}" is not a valid permission name.`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const state = permissionsOps.request(desc);
|
|
||||||
return Promise.resolve(cache(desc, state) as PermissionStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.defineProperty(PermissionStatusImpl, "name", {
|
|
||||||
value: "PermissionStatus",
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
Object.defineProperty(PermissionsImpl, "name", {
|
|
||||||
value: "Permissions",
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
|
@ -1,5 +1,5 @@
|
||||||
window.onload = async (): Promise<void> => {
|
window.onload = async (): Promise<void> => {
|
||||||
console.log(performance.now() % 2 !== 0);
|
console.log(performance.now() % 2 !== 0);
|
||||||
await navigator.permissions.revoke({ name: "hrtime" });
|
await Deno.permissions.revoke({ name: "hrtime" });
|
||||||
console.log(performance.now() % 2 === 0);
|
console.log(performance.now() % 2 === 0);
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,11 +18,11 @@ export function assert(cond: unknown): asserts cond {
|
||||||
|
|
||||||
function genFunc(grant: Deno.PermissionName): [string, () => Promise<void>] {
|
function genFunc(grant: Deno.PermissionName): [string, () => Promise<void>] {
|
||||||
const gen: () => Promise<void> = async function Granted(): Promise<void> {
|
const gen: () => Promise<void> = async function Granted(): Promise<void> {
|
||||||
const status0 = await navigator.permissions.query({ name: grant });
|
const status0 = await Deno.permissions.query({ name: grant });
|
||||||
assert(status0 != null);
|
assert(status0 != null);
|
||||||
assert(status0.state === "granted");
|
assert(status0.state === "granted");
|
||||||
|
|
||||||
const status1 = await navigator.permissions.revoke({ name: grant });
|
const status1 = await Deno.permissions.revoke({ name: grant });
|
||||||
assert(status1 != null);
|
assert(status1 != null);
|
||||||
assert(status1.state === "prompt");
|
assert(status1.state === "prompt");
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,40 +1,27 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { unitTest, assert } from "./test_util.ts";
|
||||||
import { unitTest, assert, assertThrowsAsync } from "./test_util.ts";
|
|
||||||
|
|
||||||
unitTest(async function permissionInvalidName(): Promise<void> {
|
unitTest(async function permissionInvalidName(): Promise<void> {
|
||||||
await assertThrowsAsync(async () => {
|
let thrown = false;
|
||||||
// @ts-expect-error name should not accept "foo"
|
try {
|
||||||
await navigator.permissions.query({ name: "foo" });
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
}, TypeError);
|
await Deno.permissions.query({ name: "foo" as any });
|
||||||
|
} catch (e) {
|
||||||
|
thrown = true;
|
||||||
|
assert(e instanceof Error);
|
||||||
|
} finally {
|
||||||
|
assert(thrown);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
unitTest(async function permissionNetInvalidUrl(): Promise<void> {
|
unitTest(async function permissionNetInvalidUrl(): Promise<void> {
|
||||||
await assertThrowsAsync(async () => {
|
let thrown = false;
|
||||||
await navigator.permissions.query({ name: "net", url: ":" });
|
try {
|
||||||
}, URIError);
|
await Deno.permissions.query({ name: "net", url: ":" });
|
||||||
});
|
} catch (e) {
|
||||||
|
thrown = true;
|
||||||
unitTest(async function permissionQueryReturnsEventTarget(): Promise<void> {
|
assert(e instanceof URIError);
|
||||||
const status = await navigator.permissions.query({ name: "hrtime" });
|
} finally {
|
||||||
assert(["granted", "denied", "prompt"].includes(status.state));
|
assert(thrown);
|
||||||
let called = false;
|
}
|
||||||
status.addEventListener("change", () => {
|
|
||||||
called = true;
|
|
||||||
});
|
|
||||||
status.dispatchEvent(new Event("change"));
|
|
||||||
assert(called);
|
|
||||||
assert(status === (await navigator.permissions.query({ name: "hrtime" })));
|
|
||||||
});
|
|
||||||
|
|
||||||
unitTest(async function permissionQueryForReadReturnsSameStatus() {
|
|
||||||
const status1 = await navigator.permissions.query({
|
|
||||||
name: "read",
|
|
||||||
path: ".",
|
|
||||||
});
|
|
||||||
const status2 = await navigator.permissions.query({
|
|
||||||
name: "read",
|
|
||||||
path: ".",
|
|
||||||
});
|
|
||||||
assert(status1 === status2);
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -42,7 +42,7 @@ export function fmtPerms(perms: Permissions): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const isGranted = async (name: Deno.PermissionName): Promise<boolean> =>
|
const isGranted = async (name: Deno.PermissionName): Promise<boolean> =>
|
||||||
(await navigator.permissions.query({ name })).state === "granted";
|
(await Deno.permissions.query({ name })).state === "granted";
|
||||||
|
|
||||||
export async function getProcessPermissions(): Promise<Permissions> {
|
export async function getProcessPermissions(): Promise<Permissions> {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -49,7 +49,7 @@ async function dropWorkerPermissions(
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const perm of permsToDrop) {
|
for (const perm of permsToDrop) {
|
||||||
await navigator.permissions.revoke({ name: perm });
|
await Deno.permissions.revoke({ name: perm });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
const { PermissionDenied } = Deno.errors;
|
||||||
|
|
||||||
function getPermissionString(descriptors: Deno.PermissionDescriptor[]): string {
|
function getPermissionString(descriptors: Deno.PermissionDescriptor[]): string {
|
||||||
return descriptors.length
|
return descriptors.length
|
||||||
? ` ${descriptors
|
? ` ${descriptors
|
||||||
|
@ -61,9 +63,9 @@ export async function grant(
|
||||||
? descriptor
|
? descriptor
|
||||||
: [descriptor, ...descriptors];
|
: [descriptor, ...descriptors];
|
||||||
for (const descriptor of descriptors) {
|
for (const descriptor of descriptors) {
|
||||||
let state = (await navigator.permissions.query(descriptor)).state;
|
let state = (await Deno.permissions.query(descriptor)).state;
|
||||||
if (state === "prompt") {
|
if (state === "prompt") {
|
||||||
state = (await navigator.permissions.request(descriptor)).state;
|
state = (await Deno.permissions.request(descriptor)).state;
|
||||||
}
|
}
|
||||||
if (state === "granted") {
|
if (state === "granted") {
|
||||||
result.push(descriptor);
|
result.push(descriptor);
|
||||||
|
@ -103,13 +105,13 @@ export async function grantOrThrow(
|
||||||
? descriptor
|
? descriptor
|
||||||
: [descriptor, ...descriptors];
|
: [descriptor, ...descriptors];
|
||||||
for (const descriptor of descriptors) {
|
for (const descriptor of descriptors) {
|
||||||
const { state } = await navigator.permissions.request(descriptor);
|
const { state } = await Deno.permissions.request(descriptor);
|
||||||
if (state !== "granted") {
|
if (state !== "granted") {
|
||||||
denied.push(descriptor);
|
denied.push(descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (denied.length) {
|
if (denied.length) {
|
||||||
throw new Deno.errors.PermissionDenied(
|
throw new PermissionDenied(
|
||||||
`The following permissions have not been granted:\n${getPermissionString(
|
`The following permissions have not been granted:\n${getPermissionString(
|
||||||
denied
|
denied
|
||||||
)}`
|
)}`
|
||||||
|
|
Loading…
Reference in a new issue