@trylight/app 0.3.2 → 0.3.4

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.
@@ -1,10 +1,16 @@
1
- // Only a path on this app is a valid place to land after signing in. Anything
2
- // absolute (or protocol-relative) would make the login flow an open redirect.
1
+ import { SAME_ORIGIN_BASE } from "../platform/contract.js";
2
+ // Only a path on this app is a valid place to land after signing in. Parsed,
3
+ // not pattern-matched: browsers read `//host`, `/\host` and `/\t/host` as
4
+ // another site. The candidate is returned as given, not normalised: its
5
+ // pathname could read `//host`.
3
6
  export function safeNext(candidate) {
4
7
  if (candidate === null ||
5
8
  !candidate.startsWith("/") ||
6
- candidate.startsWith("//")) {
9
+ // The parser drops tabs and line breaks; a Location header refuses them.
10
+ [...candidate].some((character) => character < " ")) {
7
11
  return "/";
8
12
  }
9
- return candidate;
13
+ return new URL(candidate, SAME_ORIGIN_BASE).origin === SAME_ORIGIN_BASE
14
+ ? candidate
15
+ : "/";
10
16
  }
@@ -5,12 +5,16 @@ export declare const IMAGE_PATH = "/api/light/image";
5
5
  export declare const BUILD_PATH = "/api/light/build";
6
6
  export declare const INVOKE_BASE_PATH = "/api/mii/invoke";
7
7
  export declare const CHAT_BASE_PATH = "/api/mii/chat";
8
+ /** A base to resolve an app-relative path against when checking it stays on the app; never contacted. */
9
+ export declare const SAME_ORIGIN_BASE = "https://app.invalid";
8
10
  /** The platform's sign-in API, called with an app's own id. */
9
11
  export declare const PLATFORM_AUTH_PATHS: {
10
12
  signIn: string;
11
13
  requestPasswordReset: string;
12
14
  redeemPaneCode: string;
13
15
  config: string;
16
+ /** "Continue with Google / Microsoft": the platform signs the person in and returns with a one-time code. */
17
+ socialSignIn: string;
14
18
  };
15
19
  /** The platform's chat API: an app's chat route forwards any path beneath it, so a new widget route needs no SDK release. */
16
20
  export declare const PLATFORM_CHAT_PATH = "/api/app-chat/v1/chat";
@@ -11,12 +11,16 @@ export const IMAGE_PATH = `/api/${NAMESPACE}/image`;
11
11
  export const BUILD_PATH = `/api/${NAMESPACE}/build`;
12
12
  export const INVOKE_BASE_PATH = `/api/${LEGACY_NAMESPACE}/invoke`;
13
13
  export const CHAT_BASE_PATH = `/api/${LEGACY_NAMESPACE}/chat`;
14
+ /** A base to resolve an app-relative path against when checking it stays on the app; never contacted. */
15
+ export const SAME_ORIGIN_BASE = "https://app.invalid";
14
16
  /** The platform's sign-in API, called with an app's own id. */
15
17
  export const PLATFORM_AUTH_PATHS = {
16
18
  signIn: "/api/app-auth/sign-in",
17
19
  requestPasswordReset: "/api/app-auth/request-password-reset",
18
20
  redeemPaneCode: "/api/app-auth/redeem",
19
- config: "/api/app-auth/config"
21
+ config: "/api/app-auth/config",
22
+ /** "Continue with Google / Microsoft": the platform signs the person in and returns with a one-time code. */
23
+ socialSignIn: "/api/app-auth/social"
20
24
  };
21
25
  /** The platform's chat API: an app's chat route forwards any path beneath it, so a new widget route needs no SDK release. */
22
26
  export const PLATFORM_CHAT_PATH = "/api/app-chat/v1/chat";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trylight/app",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "The Light SDK every v2 org app depends on: entities (Drizzle tables with a typed client), sign-in, contracts and in-app chat.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",