quidproquo-webserver 0.1.1 → 0.1.2

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.
@@ -14,28 +14,35 @@ function isWebSocketAuthenticateMessage(event) {
14
14
  }
15
15
  function* askProcessOnAuthenticate(connectionId, accessToken) {
16
16
  const connection = yield* data_1.webSocketConnectionData.askGetById(connectionId);
17
- if (connection) {
18
- const apiName = yield* (0, context_1.askWebsocketReadApiNameOrThrow)();
19
- const userDirectoryName = yield* (0, quidproquo_core_1.askConfigGetGlobal)((0, config_1.getWebSocketQueueGlobalConfigKeyForUserDirectoryName)(apiName));
20
- if (userDirectoryName) {
21
- const result = yield* (0, quidproquo_core_1.askCatch)((0, quidproquo_core_1.askUserDirectorySetAccessToken)(userDirectoryName, accessToken));
22
- if (!result.success) {
23
- yield* (0, askSendMessage_1.askSendMessage)(connectionId, {
24
- type: types_1.WebSocketQueueServerMessageEventType.Unauthenticated,
25
- });
26
- return;
27
- }
28
- const decodedAccessToken = result.result;
29
- yield* data_1.webSocketConnectionData.askUpsert(Object.assign(Object.assign({}, connection), { userId: decodedAccessToken.userId, accessToken }));
17
+ // No connection record (e.g. the connect event hasn't been processed yet)
18
+ // tell the client rather than dropping the request silently, so it can
19
+ // distinguish "not authenticated" from "no reply".
20
+ if (!connection) {
21
+ yield* (0, askSendMessage_1.askSendMessage)(connectionId, {
22
+ type: types_1.WebSocketQueueServerMessageEventType.Unauthenticated,
23
+ });
24
+ return;
25
+ }
26
+ const apiName = yield* (0, context_1.askWebsocketReadApiNameOrThrow)();
27
+ const userDirectoryName = yield* (0, quidproquo_core_1.askConfigGetGlobal)((0, config_1.getWebSocketQueueGlobalConfigKeyForUserDirectoryName)(apiName));
28
+ if (userDirectoryName) {
29
+ const result = yield* (0, quidproquo_core_1.askCatch)((0, quidproquo_core_1.askUserDirectorySetAccessToken)(userDirectoryName, accessToken));
30
+ if (!result.success) {
30
31
  yield* (0, askSendMessage_1.askSendMessage)(connectionId, {
31
- type: types_1.WebSocketQueueServerMessageEventType.Authenticated,
32
+ type: types_1.WebSocketQueueServerMessageEventType.Unauthenticated,
32
33
  });
33
- // Send a websocket message to the event buss WITHOUT an access token
34
- const webSocketQueueClientEventMessageAuthenticate = {
35
- type: types_1.WebSocketQueueClientMessageEventType.Authenticate,
36
- payload: {},
37
- };
38
- yield* (0, askBroadcastUnknownMessage_1.askBroadcastUnknownMessage)(webSocketQueueClientEventMessageAuthenticate);
34
+ return;
39
35
  }
36
+ const decodedAccessToken = result.result;
37
+ yield* data_1.webSocketConnectionData.askUpsert(Object.assign(Object.assign({}, connection), { userId: decodedAccessToken.userId, accessToken }));
38
+ yield* (0, askSendMessage_1.askSendMessage)(connectionId, {
39
+ type: types_1.WebSocketQueueServerMessageEventType.Authenticated,
40
+ });
41
+ // Send a websocket message to the event buss WITHOUT an access token
42
+ const webSocketQueueClientEventMessageAuthenticate = {
43
+ type: types_1.WebSocketQueueClientMessageEventType.Authenticate,
44
+ payload: {},
45
+ };
46
+ yield* (0, askBroadcastUnknownMessage_1.askBroadcastUnknownMessage)(webSocketQueueClientEventMessageAuthenticate);
40
47
  }
41
48
  }
@@ -4,6 +4,7 @@ import { HTTPEvent, HTTPEventResponse } from '../types/HTTPEvent';
4
4
  export declare const rawFromJsonEventRequest: (httpJsonEvent: HTTPEvent) => string | undefined;
5
5
  export declare const fromJsonEventRequest: <T>(httpJsonEvent: HTTPEvent) => T;
6
6
  export declare function askFromJsonEventRequest<T>(httpJsonEvent: HTTPEvent): AskResponse<T>;
7
+ export declare const readUriQueryParamFromEvent: (event: HTTPEvent, paramName: string) => string | undefined;
7
8
  export declare const toJsonEventResponse: (item: any, status?: number) => HTTPEventResponse;
8
9
  export declare const toHtmlResponse: (html: string, status?: number) => HTTPEventResponse;
9
10
  export declare const toTextResponse: (text: string, status?: number) => HTTPEventResponse;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toCdnResponse = exports.toMovedTemporarilyRedirectResponse = exports.toMovedPermanentlyRedirectResponse = exports.toTextResponse = exports.toHtmlResponse = exports.toJsonEventResponse = exports.fromJsonEventRequest = exports.rawFromJsonEventRequest = void 0;
3
+ exports.toCdnResponse = exports.toMovedTemporarilyRedirectResponse = exports.toMovedPermanentlyRedirectResponse = exports.toTextResponse = exports.toHtmlResponse = exports.toJsonEventResponse = exports.readUriQueryParamFromEvent = exports.fromJsonEventRequest = exports.rawFromJsonEventRequest = void 0;
4
4
  exports.askFromJsonEventRequest = askFromJsonEventRequest;
5
5
  const quidproquo_core_1 = require("quidproquo-core");
6
6
  const rawFromJsonEventRequest = (httpJsonEvent) => {
@@ -39,6 +39,14 @@ function* askFromJsonEventRequest(httpJsonEvent) {
39
39
  return yield* (0, quidproquo_core_1.askThrowError)(quidproquo_core_1.ErrorTypeEnum.BadRequest, 'Unable to parse incoming json from HTTPEvent.');
40
40
  }
41
41
  }
42
+ const readUriQueryParamFromEvent = (event, paramName) => {
43
+ const rawValue = event.query[paramName];
44
+ if (!rawValue) {
45
+ return undefined;
46
+ }
47
+ return Array.isArray(rawValue) ? rawValue[0] : rawValue;
48
+ };
49
+ exports.readUriQueryParamFromEvent = readUriQueryParamFromEvent;
42
50
  const toJsonEventResponse = (item, status = 200) => {
43
51
  return {
44
52
  status,
@@ -22,7 +22,7 @@ const isAbsoluteUrl = (url) => /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
22
22
  // Join basePath + url like axios' combineURLs (path concatenation), NOT URL
23
23
  // resolution. `new URL('/v1/x', 'http://host/api/svc')` drops the base path
24
24
  // because a leading-slash url is root-absolute; we want '.../api/svc/v1/x'.
25
- const combineUrls = (basePath, url) => url ? `${basePath.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}` : basePath;
25
+ const combineUrls = (basePath, url) => (url ? `${basePath.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}` : basePath);
26
26
  const buildRequestUrl = (payload) => {
27
27
  const fullUrl = payload.basePath && !isAbsoluteUrl(payload.url) ? combineUrls(payload.basePath, payload.url) : payload.url;
28
28
  const url = new URL(fullUrl);
@@ -10,32 +10,39 @@ export function isWebSocketAuthenticateMessage(event) {
10
10
  }
11
11
  export function* askProcessOnAuthenticate(connectionId, accessToken) {
12
12
  const connection = yield* webSocketConnectionData.askGetById(connectionId);
13
- if (connection) {
14
- const apiName = yield* askWebsocketReadApiNameOrThrow();
15
- const userDirectoryName = yield* askConfigGetGlobal(getWebSocketQueueGlobalConfigKeyForUserDirectoryName(apiName));
16
- if (userDirectoryName) {
17
- const result = yield* askCatch(askUserDirectorySetAccessToken(userDirectoryName, accessToken));
18
- if (!result.success) {
19
- yield* askSendMessage(connectionId, {
20
- type: WebSocketQueueServerMessageEventType.Unauthenticated,
21
- });
22
- return;
23
- }
24
- const decodedAccessToken = result.result;
25
- yield* webSocketConnectionData.askUpsert({
26
- ...connection,
27
- userId: decodedAccessToken.userId,
28
- accessToken,
29
- });
13
+ // No connection record (e.g. the connect event hasn't been processed yet)
14
+ // tell the client rather than dropping the request silently, so it can
15
+ // distinguish "not authenticated" from "no reply".
16
+ if (!connection) {
17
+ yield* askSendMessage(connectionId, {
18
+ type: WebSocketQueueServerMessageEventType.Unauthenticated,
19
+ });
20
+ return;
21
+ }
22
+ const apiName = yield* askWebsocketReadApiNameOrThrow();
23
+ const userDirectoryName = yield* askConfigGetGlobal(getWebSocketQueueGlobalConfigKeyForUserDirectoryName(apiName));
24
+ if (userDirectoryName) {
25
+ const result = yield* askCatch(askUserDirectorySetAccessToken(userDirectoryName, accessToken));
26
+ if (!result.success) {
30
27
  yield* askSendMessage(connectionId, {
31
- type: WebSocketQueueServerMessageEventType.Authenticated,
28
+ type: WebSocketQueueServerMessageEventType.Unauthenticated,
32
29
  });
33
- // Send a websocket message to the event buss WITHOUT an access token
34
- const webSocketQueueClientEventMessageAuthenticate = {
35
- type: WebSocketQueueClientMessageEventType.Authenticate,
36
- payload: {},
37
- };
38
- yield* askBroadcastUnknownMessage(webSocketQueueClientEventMessageAuthenticate);
30
+ return;
39
31
  }
32
+ const decodedAccessToken = result.result;
33
+ yield* webSocketConnectionData.askUpsert({
34
+ ...connection,
35
+ userId: decodedAccessToken.userId,
36
+ accessToken,
37
+ });
38
+ yield* askSendMessage(connectionId, {
39
+ type: WebSocketQueueServerMessageEventType.Authenticated,
40
+ });
41
+ // Send a websocket message to the event buss WITHOUT an access token
42
+ const webSocketQueueClientEventMessageAuthenticate = {
43
+ type: WebSocketQueueClientMessageEventType.Authenticate,
44
+ payload: {},
45
+ };
46
+ yield* askBroadcastUnknownMessage(webSocketQueueClientEventMessageAuthenticate);
40
47
  }
41
48
  }
@@ -4,6 +4,7 @@ import { HTTPEvent, HTTPEventResponse } from '../types/HTTPEvent';
4
4
  export declare const rawFromJsonEventRequest: (httpJsonEvent: HTTPEvent) => string | undefined;
5
5
  export declare const fromJsonEventRequest: <T>(httpJsonEvent: HTTPEvent) => T;
6
6
  export declare function askFromJsonEventRequest<T>(httpJsonEvent: HTTPEvent): AskResponse<T>;
7
+ export declare const readUriQueryParamFromEvent: (event: HTTPEvent, paramName: string) => string | undefined;
7
8
  export declare const toJsonEventResponse: (item: any, status?: number) => HTTPEventResponse;
8
9
  export declare const toHtmlResponse: (html: string, status?: number) => HTTPEventResponse;
9
10
  export declare const toTextResponse: (text: string, status?: number) => HTTPEventResponse;
@@ -33,6 +33,13 @@ export function* askFromJsonEventRequest(httpJsonEvent) {
33
33
  return yield* askThrowError(ErrorTypeEnum.BadRequest, 'Unable to parse incoming json from HTTPEvent.');
34
34
  }
35
35
  }
36
+ export const readUriQueryParamFromEvent = (event, paramName) => {
37
+ const rawValue = event.query[paramName];
38
+ if (!rawValue) {
39
+ return undefined;
40
+ }
41
+ return Array.isArray(rawValue) ? rawValue[0] : rawValue;
42
+ };
36
43
  export const toJsonEventResponse = (item, status = 200) => {
37
44
  return {
38
45
  status,
@@ -10,7 +10,7 @@ const isAbsoluteUrl = (url) => /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
10
10
  // Join basePath + url like axios' combineURLs (path concatenation), NOT URL
11
11
  // resolution. `new URL('/v1/x', 'http://host/api/svc')` drops the base path
12
12
  // because a leading-slash url is root-absolute; we want '.../api/svc/v1/x'.
13
- const combineUrls = (basePath, url) => url ? `${basePath.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}` : basePath;
13
+ const combineUrls = (basePath, url) => (url ? `${basePath.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}` : basePath);
14
14
  const buildRequestUrl = (payload) => {
15
15
  const fullUrl = payload.basePath && !isAbsoluteUrl(payload.url) ? combineUrls(payload.basePath, payload.url) : payload.url;
16
16
  const url = new URL(fullUrl);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-webserver",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -33,10 +33,10 @@
33
33
  "homepage": "https://github.com/joe-coady/quidproquo#readme",
34
34
  "dependencies": {
35
35
  "@anthropic-ai/sdk": "^0.19.1",
36
- "quidproquo-core": "0.1.1"
36
+ "quidproquo-core": "0.1.2"
37
37
  },
38
38
  "devDependencies": {
39
- "quidproquo-tsconfig": "0.1.1",
39
+ "quidproquo-tsconfig": "0.1.2",
40
40
  "typescript": "^5.8.2"
41
41
  }
42
42
  }