@bkazemi/verily 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -168,7 +168,7 @@ import { init } from '@bkazemi/verily';
168
168
  const client = init({ backendUrl: '/api/verily' });
169
169
  ```
170
170
 
171
- Without one, serve `node_modules/@bkazemi/verily/dist/verily.js` yourself, or load it from a CDN such as `https://cdn.jsdelivr.net/npm/@bkazemi/verily@0.9.0/dist/verily.js`. The script defines a global `Verily`.
171
+ Without one, serve `node_modules/@bkazemi/verily/dist/verily.js` yourself, or load it from a CDN such as `https://cdn.jsdelivr.net/npm/@bkazemi/verily@0.9.1/dist/verily.js`. The script defines a global `Verily`.
172
172
 
173
173
  Then place the badge wherever the account appears:
174
174
 
@@ -370,7 +370,7 @@ A static site only needs the script and the badge markup; the backend runs somew
370
370
 
371
371
  ```html
372
372
  <script
373
- src="https://cdn.jsdelivr.net/npm/@bkazemi/verily@0.9.0/dist/verily.js"
373
+ src="https://cdn.jsdelivr.net/npm/@bkazemi/verily@0.9.1/dist/verily.js"
374
374
  defer
375
375
  ></script>
376
376
  <verily-badge
@@ -195,7 +195,7 @@ class Server {
195
195
  this.auth = new OwnerAuth(this.store, options.ownerKey);
196
196
  this.sites = new Sites(this.store, options.sites ?? new Map());
197
197
  this.dashboard = new Dashboard(this.store, this.sites, options.providers, origin.host, options.reportUrl);
198
- this.ownerSites = new OwnerSites(this.store, this.sites);
198
+ this.ownerSites = new OwnerSites(this.store, this.sites, options.providers);
199
199
  if (options.registration === 'open')
200
200
  this.registrations = new Registrations(this.store, this.sites, this.origin, options.dns);
201
201
  const ownerOrigin = new URL(options.owner.profileUrl).origin;
@@ -704,7 +704,7 @@ class Server {
704
704
  <a class="button" href="/verify">Verify an account</a>${!site &&
705
705
  html `
706
706
  <a href="/records">Every connection on this instance</a>
707
- <a href="/sites">Registered sites</a>
707
+ <a href="/sites">Sites</a>
708
708
  `}
709
709
  </p>
710
710
  ${connections.length
@@ -1,17 +1,24 @@
1
+ import type { Provider } from '../core/index.js';
1
2
  import { type Sites } from './sites.js';
2
3
  import type { Store } from './store.js';
3
4
  /**
4
5
  * Where the instance owner oversees the sites registered here: suspends one by hand, sets
5
- * its request limit, and approves it for YouTube. Sites in `SITES` are the host's, and are
6
- * not listed.
6
+ * its request limit, and approves it for YouTube. Sites in `SITES` are listed apart, read
7
+ * only, since they are changed in the configuration.
7
8
  */
8
9
  export declare class OwnerSites {
9
10
  private readonly store;
10
11
  private readonly sites;
11
- constructor(store: Store, sites: Sites);
12
- /** Every stored site, with how it stands and the owner's controls over it. */
12
+ private readonly providers;
13
+ constructor(store: Store, sites: Sites, providers: Provider[]);
14
+ /**
15
+ * Every stored site, with how it stands and the owner's controls over it, then every site
16
+ * in `SITES`.
17
+ */
13
18
  page(): Promise<Response>;
14
19
  /** One of the page's forms, sent to `path`. Every one returns to the page. */
15
20
  change(path: string, request: Request): Promise<Response>;
21
+ /** A site in `SITES`, as it is configured. */
22
+ private configuredRow;
16
23
  private row;
17
24
  }
@@ -7,17 +7,22 @@ import { dnsPrefix } from './sites.js';
7
7
  const maxLimit = 100000;
8
8
  /**
9
9
  * Where the instance owner oversees the sites registered here: suspends one by hand, sets
10
- * its request limit, and approves it for YouTube. Sites in `SITES` are the host's, and are
11
- * not listed.
10
+ * its request limit, and approves it for YouTube. Sites in `SITES` are listed apart, read
11
+ * only, since they are changed in the configuration.
12
12
  */
13
13
  export class OwnerSites {
14
14
  store;
15
15
  sites;
16
- constructor(store, sites) {
16
+ providers;
17
+ constructor(store, sites, providers) {
17
18
  this.store = store;
18
19
  this.sites = sites;
20
+ this.providers = providers;
19
21
  }
20
- /** Every stored site, with how it stands and the owner's controls over it. */
22
+ /**
23
+ * Every stored site, with how it stands and the owner's controls over it, then every site
24
+ * in `SITES`.
25
+ */
21
26
  async page() {
22
27
  const stored = this.sites.stored();
23
28
  const rows = await Promise.all(stored.map(async (site) => {
@@ -25,7 +30,9 @@ export class OwnerSites {
25
30
  const registered = (await this.sites.operators(site.id))[0]?.addedAt;
26
31
  return this.row(site, check, registered);
27
32
  }));
28
- return respond('Registered sites', html `
33
+ const configured = this.sites.configured();
34
+ return respond('Sites', html `
35
+ <h2>Registered here</h2>
29
36
  ${stored.length
30
37
  ? html `
31
38
  <p class="fine">
@@ -36,6 +43,16 @@ export class OwnerSites {
36
43
  ${rows}
37
44
  `
38
45
  : html `<p>No sites are registered here.</p>`}
46
+ ${configured.length > 0 &&
47
+ html `
48
+ <h2>Set by the host</h2>
49
+ <p class="fine">
50
+ These sites are set in the instance's <code>SITES</code> setting and change only
51
+ with it. Their DNS is not checked, and they cannot be suspended, limited or held
52
+ back from YouTube here.
53
+ </p>
54
+ ${configured.map((site) => this.configuredRow(site))}
55
+ `}
39
56
  <p><a href="/">Back to owner settings</a></p>
40
57
  `);
41
58
  }
@@ -60,7 +77,7 @@ export class OwnerSites {
60
77
  if (given && !(Number.isInteger(limit) && limit >= 1 && limit <= maxLimit))
61
78
  return respond('Limit not changed', html `
62
79
  <p>A limit is a whole number of requests a minute, from 1 to ${maxLimit}.</p>
63
- <p><a href="/sites">Back to registered sites</a></p>
80
+ <p><a href="/sites">Back to sites</a></p>
64
81
  `, 400, 'single');
65
82
  await this.sites.control(id, ({ limit: _, ...rest }) => (given ? { ...rest, limit } : rest));
66
83
  }
@@ -68,6 +85,33 @@ export class OwnerSites {
68
85
  return unavailable();
69
86
  return see('/sites');
70
87
  }
88
+ /** A site in `SITES`, as it is configured. */
89
+ configuredRow(site) {
90
+ const names = new Map(this.providers.map((provider) => [provider.id, provider.name]));
91
+ const providers = site.providers
92
+ ? site.providers.map((id) => names.get(id) ?? id).join(', ')
93
+ : 'Every one offered';
94
+ const visibility = site.visibility
95
+ ? site.visibility.map((v) => v[0].toUpperCase() + v.slice(1)).join(', ')
96
+ : 'Public, Unlisted';
97
+ return html `
98
+ <section>
99
+ <h3>${site.name}</h3>
100
+ <dl>
101
+ <dt>Site id</dt>
102
+ <dd>${site.id}</dd>
103
+ <dt>Origin</dt>
104
+ <dd><a href="${site.origin}">${site.origin}</a></dd>
105
+ <dt>Providers</dt>
106
+ <dd>${providers}</dd>
107
+ <dt>Visibility</dt>
108
+ <dd>${visibility}</dd>
109
+ <dt>Request limit</dt>
110
+ <dd>${limits.site} a minute</dd>
111
+ </dl>
112
+ </section>
113
+ `;
114
+ }
71
115
  row(site, check, registered) {
72
116
  const controls = this.sites.controls.get(site.id) ?? {};
73
117
  const standing = controls.suspendedAt !== undefined
@@ -80,7 +124,7 @@ export class OwnerSites {
80
124
  const hidden = html `<input type="hidden" name="id" value="${site.id}">`;
81
125
  return html `
82
126
  <section>
83
- <h2>${site.name}</h2>
127
+ <h3>${site.name}</h3>
84
128
  <dl>
85
129
  <dt>Site id</dt>
86
130
  <dd>${site.id}</dd>
@@ -155,6 +155,8 @@ export declare class Sites {
155
155
  * registered, changed or removed by another process is served as it now is.
156
156
  */
157
157
  refresh(): Promise<void>;
158
+ /** The sites the host configures in `SITES`. */
159
+ configured(): Site[];
158
160
  /** The sites kept in the store and served, which are the ones whose DNS is checked. */
159
161
  stored(): Site[];
160
162
  /**
@@ -241,6 +241,10 @@ export class Sites {
241
241
  this.suspended = suspended;
242
242
  this.controls = controls;
243
243
  }
244
+ /** The sites the host configures in `SITES`. */
245
+ configured() {
246
+ return [...this.pinned.values()];
247
+ }
244
248
  /** The sites kept in the store and served, which are the ones whose DNS is checked. */
245
249
  stored() {
246
250
  return [...this.sites.values()].filter((site) => !this.pinned.has(site.id));
package/dist/verily.js CHANGED
@@ -10520,7 +10520,7 @@ ${claims(evidence)}`;
10520
10520
  }
10521
10521
 
10522
10522
  // src/version.ts
10523
- var version = "v0.9.0";
10523
+ var version = "v0.9.1";
10524
10524
 
10525
10525
  // src/browser/evidence-dialog.ts
10526
10526
  function stampLink() {
package/dist/version.d.ts CHANGED
@@ -7,4 +7,4 @@
7
7
  * output stays what tsc emitted and nothing has to be substituted into it. A version bump
8
8
  * changes this line with package.json.
9
9
  */
10
- export declare const version = "v0.9.0";
10
+ export declare const version = "v0.9.1";
package/dist/version.js CHANGED
@@ -7,4 +7,4 @@
7
7
  * output stays what tsc emitted and nothing has to be substituted into it. A version bump
8
8
  * changes this line with package.json.
9
9
  */
10
- export const version = 'v0.9.0';
10
+ export const version = 'v0.9.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bkazemi/verily",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Self-hosted account-to-account verification for Node.js",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -44,7 +44,7 @@
44
44
  "prettier": "3.9.6",
45
45
  "tsx": "^4.20.0",
46
46
  "typescript": "^5.9.0",
47
- "wrangler": "^4.132.0"
47
+ "wrangler": "^4.151.0"
48
48
  },
49
49
  "workspaces": [
50
50
  "example"