askgloss 0.1.0 → 0.1.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/dist/cli/index.js CHANGED
@@ -48,9 +48,8 @@ async function checkKey(apiKey) {
48
48
  const response = await fetch('https://api.openai.com/v1/models', { headers: { Authorization: 'Bearer ' + apiKey }, signal: AbortSignal.timeout(15000) }).catch(() => null);
49
49
  if (!response)
50
50
  return 'Could not reach OpenAI. Check your internet connection.';
51
- if (response.status === 401)
52
- return 'OpenAI rejected that key.';
53
- return response.ok ? '' : `OpenAI returned an error (${response.status}).`;
51
+ // Only a rejected key is fatal. Restricted keys may lack permission to list models yet still run Gloss.
52
+ return response.status === 401 ? 'OpenAI rejected that key.' : '';
54
53
  }
55
54
  // Exiting through process.exit while a fetch socket is still open crashes Node on Windows, so failures set exitCode and return.
56
55
  async function getKey() {
@@ -82,6 +81,11 @@ async function getKey() {
82
81
  return apiKey;
83
82
  }
84
83
  const port = Number(option('--port') || process.env.PORT || 3000);
84
+ // Only Gloss may spend this key: other extensions with access to 127.0.0.1 are refused. EXTENSION_ID
85
+ // (comma-separated) replaces the list, for example for an unpacked build loaded from another folder.
86
+ // TODO: add the Chrome Web Store ID once the listing exists.
87
+ const glossExtensionIds = ['onooiajelfmchgbghniiaogkaahgkmpc', 'hlbhiofbfhhfhcbgohbmhgkhdnmpfcjm'];
88
+ const extensionIds = process.env.EXTENSION_ID?.split(',').map(id => id.trim()).filter(Boolean) || glossExtensionIds;
85
89
  // Only problems reach the terminal; conversations and page content are never printed.
86
90
  const log = (event, details = {}) => {
87
91
  if (event === 'openai.error')
@@ -93,7 +97,7 @@ const apiKey = await getKey();
93
97
  if (!apiKey)
94
98
  process.exitCode = 1;
95
99
  else {
96
- const server = createApp({ apiKey, log, accessToken: '', clerkJwtKey: '' });
100
+ const server = createApp({ apiKey, log, accessToken: '', clerkJwtKey: '', extensionIds });
97
101
  server.on('error', (error) => {
98
102
  console.error(error.code === 'EADDRINUSE' ? `Port ${port} is already in use. Is Gloss already running? Otherwise try \`npx askgloss --port ${port + 1}\`.` : error.message);
99
103
  process.exitCode = 1;
@@ -67,7 +67,7 @@ async function readJson(req, limit) {
67
67
  }
68
68
  }
69
69
  const listFromEnv = (value) => (value || '').split(',').map(item => item.trim()).filter(Boolean);
70
- export function createHandler({ apiKey = process.env.OPENAI_API_KEY, accessToken = process.env.ACCESS_TOKEN, clerkJwtKey = process.env.CLERK_JWT_KEY, authorizedParties = listFromEnv(process.env.CLERK_AUTHORIZED_PARTIES), extensionId = process.env.EXTENSION_ID, usage = createUsage(), fetchImpl = fetch, log = createLogger() } = {}) {
70
+ export function createHandler({ apiKey = process.env.OPENAI_API_KEY, accessToken = process.env.ACCESS_TOKEN, clerkJwtKey = process.env.CLERK_JWT_KEY, authorizedParties = listFromEnv(process.env.CLERK_AUTHORIZED_PARTIES), extensionIds = listFromEnv(process.env.EXTENSION_ID), usage = createUsage(), fetchImpl = fetch, log = createLogger() } = {}) {
71
71
  const authenticate = createAuth({ accessToken, clerkJwtKey, authorizedParties });
72
72
  async function callOpenAI(path, body) {
73
73
  if (!apiKey)
@@ -141,7 +141,7 @@ export function createHandler({ apiKey = process.env.OPENAI_API_KEY, accessToken
141
141
  async function handle(req, requestId) {
142
142
  // Only the extension may call this server. Never enable website CORS.
143
143
  const origin = req.headers.origin;
144
- if (origin && (!/^chrome-extension:\/\/[a-p]{32}$/.test(origin) || (extensionId && origin !== 'chrome-extension://' + extensionId)))
144
+ if (origin && (!/^chrome-extension:\/\/[a-p]{32}$/.test(origin) || (extensionIds.length && !extensionIds.includes(origin.slice(19)))))
145
145
  throw new HttpError(403, 'Only the browser extension can connect.');
146
146
  // Vercel's rewrite adds the route as a query string; only the path matters.
147
147
  const path = (req.url || '').split('?')[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "askgloss",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Run the Gloss server on your computer with your own OpenAI API key.",
5
5
  "homepage": "https://askgloss.app",
6
6
  "repository": { "type": "git", "url": "git+https://github.com/adamblumoff/browser-live-ui.git", "directory": "cli" },