@digital-ai/dot-illustrations 2.0.43 → 2.0.45

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.
@@ -91,7 +91,7 @@ jobs:
91
91
  registry-url: 'https://registry.npmjs.org'
92
92
 
93
93
  - name: Update npm (≥ 11.5.1 required for OIDC)
94
- run: npm install -g npm@latest
94
+ run: npm install -g npm@11
95
95
 
96
96
  - name: Publish to npm
97
97
  run: npm publish --access public
package/README.md CHANGED
@@ -106,7 +106,11 @@ The demo includes a built-in upload flow that handles everything automatically.
106
106
 
107
107
  #### Prerequisites
108
108
 
109
- Run the local proxy once so the demo can authenticate as you without entering a token:
109
+ **On the hosted demo** (`digital-ai.github.io/dot-illustrations/demo/`): nothing to run yourself — click **Connect GitHub** and follow the device-code prompt. This works because a maintainer has deployed the `demo/oauth-proxy/` Worker + registered a GitHub OAuth App (one-time setup, see [`demo/oauth-proxy/`](demo/oauth-proxy/)). GitHub's device-flow endpoints don't support CORS, so the browser can't call them directly the Worker forwards those two calls server-to-server. It holds no secrets; Device Flow for public OAuth Apps only needs the Client ID.
110
+
111
+ If that isn't configured yet, **Connect GitHub** falls back to a manual Personal Access Token paste-in (scope: `public_repo`).
112
+
113
+ **Running locally instead:** run the local proxy once so the demo can authenticate as you without entering a token:
110
114
 
111
115
  ```bash
112
116
  # From the repo root (requires gh CLI authenticated: gh auth login)
@@ -123,19 +127,19 @@ node demo/local-proxy.js
123
127
  - Enter the **Illustration ID** (lowercase, hyphens only — e.g. `my-new-state`)
124
128
  - Select the **Category**: Global or Dashboards
125
129
  - Upload the **Light SVG** (☀️) and **Dark SVG** (🌙) — both are required
126
- - Click **Connect GitHub** then **Create Pull Request**
130
+ - Click **Connect GitHub** (device-code prompt on the hosted demo, local `gh auth` session with the local proxy running, or PAT paste-in fallback) then **Create Pull Request**
127
131
 
128
132
  **Integration logo**
129
133
  - Enter the **Integration ID** (lowercase, hyphens — e.g. `my-tool`)
130
134
  - Upload the single **SVG** file (no dark variant needed)
131
- - Click **Connect GitHub** then **Create Pull Request**
135
+ - Click **Connect GitHub** (device-code prompt on the hosted demo, local `gh auth` session with the local proxy running, or PAT paste-in fallback) then **Create Pull Request**
132
136
 
133
137
  The PR is created automatically with:
134
138
  - SVG file(s) committed to the correct folder
135
139
  - CSS rule added to `index.css`
136
140
  - ID added to `demo/script.js` in alphabetical order
137
141
 
138
- > The local proxy uses your existing `gh auth` credentials — no token input required.
142
+ > The local proxy uses your existing `gh auth` credentials — no token input required. The hosted demo's Connect GitHub button uses the device-flow proxy instead (see Prerequisites above); if it's not yet configured, it falls back to PAT paste-in.
139
143
 
140
144
  ---
141
145
 
@@ -6,11 +6,18 @@
6
6
  * 1. Register a GitHub OAuth App at https://github.com/settings/developers
7
7
  * - Homepage: https://digital-ai.github.io/dot-illustrations/demo/
8
8
  * - Check "Enable Device Flow" — no callback URL needed
9
- * 2. Set GITHUB_OAUTH_CLIENT_ID to your Client ID
9
+ * 2. Replace CLIENT_ID below with your app's Client ID
10
+ * 3. The Client ID is public-safe — only the Client Secret must stay private,
11
+ * and Device Flow never requires the secret in the browser.
12
+ * 4. Deploy demo/oauth-proxy/ (Cloudflare Worker) — GitHub's device-flow
13
+ * endpoints don't support CORS, so the browser can't call them directly;
14
+ * the Worker forwards those two calls server-to-server. Holds no secrets.
15
+ * 5. Replace OAUTH_PROXY_URL below with the deployed Worker's *.workers.dev URL.
10
16
  */
11
17
 
12
18
  const GITHUB_UPLOAD_CONFIG = {
13
- CLIENT_ID: 'YOUR_GITHUB_OAUTH_CLIENT_ID',
19
+ CLIENT_ID: 'Ov23liJSaMsvgE5Q51cI',
20
+ OAUTH_PROXY_URL: 'https://dot-illustrations-oauth-proxy.dot-icons.workers.dev',
14
21
  REPO_OWNER: 'digital-ai',
15
22
  REPO_NAME: 'dot-illustrations',
16
23
  BASE_BRANCH: 'main',
@@ -132,12 +139,20 @@ async function ghCreatePR(head, title, body) {
132
139
  }
133
140
 
134
141
  // ─── Device Flow ─────────────────────────────────────────────────────────────
142
+ // Both calls go through demo/oauth-proxy/ (Cloudflare Worker) — GitHub's
143
+ // device-flow endpoints don't support CORS, so the browser can't call
144
+ // github.com directly.
135
145
 
136
146
  async function ghStartDeviceFlow() {
137
- if (!GITHUB_UPLOAD_CONFIG.CLIENT_ID || GITHUB_UPLOAD_CONFIG.CLIENT_ID === 'YOUR_GITHUB_OAUTH_CLIENT_ID') {
147
+ if (
148
+ !GITHUB_UPLOAD_CONFIG.CLIENT_ID ||
149
+ GITHUB_UPLOAD_CONFIG.CLIENT_ID === 'YOUR_GITHUB_OAUTH_CLIENT_ID' ||
150
+ !GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL ||
151
+ GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL === 'YOUR_OAUTH_PROXY_WORKERS_DEV_URL'
152
+ ) {
138
153
  throw new Error('NO_CLIENT_ID');
139
154
  }
140
- const resp = await fetch('https://github.com/login/device/code', {
155
+ const resp = await fetch(`${GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL}/device/code`, {
141
156
  method: 'POST',
142
157
  headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
143
158
  body: JSON.stringify({ client_id: GITHUB_UPLOAD_CONFIG.CLIENT_ID, scope: GITHUB_UPLOAD_CONFIG.SCOPES }),
@@ -150,7 +165,7 @@ function ghPollForToken(deviceCode, intervalSec) {
150
165
  return new Promise((resolve, reject) => {
151
166
  const timer = setInterval(async () => {
152
167
  try {
153
- const resp = await fetch('https://github.com/login/oauth/access_token', {
168
+ const resp = await fetch(`${GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL}/access_token`, {
154
169
  method: 'POST',
155
170
  headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
156
171
  body: JSON.stringify({
@@ -0,0 +1,23 @@
1
+ # OAuth device-flow proxy
2
+
3
+ Stateless Cloudflare Worker that forwards `POST /device/code` and `POST /access_token`
4
+ to GitHub's device-flow endpoints. Exists only because those endpoints don't support
5
+ CORS, so a static page can't call them directly from the browser. Holds no secrets —
6
+ device flow for public GitHub OAuth Apps only needs the Client ID, which the browser
7
+ already sends.
8
+
9
+ ## Deploy (one-time, per maintainer/environment)
10
+
11
+ ```bash
12
+ cd demo/oauth-proxy
13
+ npx wrangler login
14
+ npx wrangler deploy
15
+ ```
16
+
17
+ This prints a `*.workers.dev` URL. Then:
18
+
19
+ 1. Put that URL into `OAUTH_PROXY_URL` in [`demo/github-upload.js`](../github-upload.js)
20
+ 2. Put your GitHub OAuth App's Client ID into `CLIENT_ID` in the same file (see the
21
+ file's header comment for how to register the OAuth App)
22
+ 3. If the demo isn't served from `https://digital-ai.github.io`, update
23
+ `ALLOWED_ORIGIN` in [`wrangler.toml`](./wrangler.toml) to match
@@ -0,0 +1,62 @@
1
+ /**
2
+ * OAuth device-flow proxy — Cloudflare Worker
3
+ *
4
+ * GitHub's device-flow endpoints (github.com/login/device/code and
5
+ * github.com/login/oauth/access_token) don't support CORS, so a static
6
+ * page can't call them directly from browser JS. This Worker forwards
7
+ * those two calls server-to-server, so the browser only ever talks to
8
+ * this Worker (which does send CORS headers).
9
+ *
10
+ * Holds no secrets: GitHub's device flow for public OAuth Apps only
11
+ * needs client_id (sent by the browser), never a client secret.
12
+ *
13
+ * Deploy: from this directory, `npx wrangler login && npx wrangler deploy`.
14
+ * Then set ALLOWED_ORIGIN below (or via `wrangler.toml` [vars]) and put the
15
+ * resulting *.workers.dev URL into demo/github-upload.js's OAUTH_PROXY_URL.
16
+ */
17
+
18
+ const GITHUB_ENDPOINTS = {
19
+ '/device/code': 'https://github.com/login/device/code',
20
+ '/access_token': 'https://github.com/login/oauth/access_token',
21
+ };
22
+
23
+ export default {
24
+ async fetch(request, env) {
25
+ const allowedOrigin = env.ALLOWED_ORIGIN || 'https://digital-ai.github.io';
26
+ const corsHeaders = {
27
+ 'Access-Control-Allow-Origin': allowedOrigin,
28
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
29
+ 'Access-Control-Allow-Headers': 'Content-Type',
30
+ };
31
+
32
+ if (request.method === 'OPTIONS') {
33
+ return new Response(null, { headers: corsHeaders });
34
+ }
35
+
36
+ const url = new URL(request.url);
37
+ const target = GITHUB_ENDPOINTS[url.pathname];
38
+
39
+ if (!target || request.method !== 'POST') {
40
+ return new Response(JSON.stringify({ error: 'Not found' }), {
41
+ status: 404,
42
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
43
+ });
44
+ }
45
+
46
+ const body = await request.text();
47
+ const upstream = await fetch(target, {
48
+ method: 'POST',
49
+ headers: {
50
+ 'Accept': 'application/json',
51
+ 'Content-Type': 'application/json',
52
+ },
53
+ body,
54
+ });
55
+
56
+ const data = await upstream.text();
57
+ return new Response(data, {
58
+ status: upstream.status,
59
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
60
+ });
61
+ },
62
+ };
@@ -0,0 +1,6 @@
1
+ name = "dot-illustrations-oauth-proxy"
2
+ main = "worker.js"
3
+ compatibility_date = "2026-01-01"
4
+
5
+ [vars]
6
+ ALLOWED_ORIGIN = "https://digital-ai.github.io"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digital-ai/dot-illustrations",
3
- "version": "2.0.43",
3
+ "version": "2.0.45",
4
4
  "description": "A central place for the design team to keep illustrations and for dev teams to find them.",
5
5
  "main": "./index.css",
6
6
  "scripts": {