@trylight/app 0.3.0 → 0.3.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/auth/core.d.ts +2 -2
- package/dist/auth/core.js +1 -1
- package/dist/auth/plaza.d.ts +8 -0
- package/dist/auth/plaza.js +27 -1
- package/dist/platform/server-fn-door.js +4 -3
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +2 -1
- package/dist/server/session.d.ts +7 -0
- package/dist/server/session.js +9 -1
- package/package.json +10 -12
package/dist/auth/core.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ import { type MiiUser, type ResolvedSession } from "./lookup.js";
|
|
|
5
5
|
import { type MiiIdentity, type PlazaSession } from "./plaza.js";
|
|
6
6
|
export type { MiiUser, ResolvedSession } from "./lookup.js";
|
|
7
7
|
export type { AuthMode } from "./mode.js";
|
|
8
|
-
export type { MiiIdentity, PlazaSession, SignedIn, SignInFailure, SignInResult } from "./plaza.js";
|
|
8
|
+
export type { MiiIdentity, PasswordResetResult, PlazaSession, SignedIn, SignInFailure, SignInResult } from "./plaza.js";
|
|
9
9
|
export { SIGN_IN_PROBLEMS } from "./problems.js";
|
|
10
10
|
export { safeNext } from "./next-path.js";
|
|
11
11
|
export { SESSION_COOKIE } from "./lookup.js";
|
|
12
|
-
export { signInWithPlaza } from "./plaza.js";
|
|
12
|
+
export { requestPasswordResetWithPlaza, signInWithPlaza } from "./plaza.js";
|
|
13
13
|
export type CreateMiiAuthCoreOptions = {
|
|
14
14
|
/** Where to report failures that are ours, not the person's. Defaults to console.error. */
|
|
15
15
|
readonly reportError?: (error: unknown, context: Record<string, string>) => void;
|
package/dist/auth/core.js
CHANGED
|
@@ -8,7 +8,7 @@ import { deactivateUser, upsertMemberFromIdentity } from "./users.js";
|
|
|
8
8
|
export { SIGN_IN_PROBLEMS } from "./problems.js";
|
|
9
9
|
export { safeNext } from "./next-path.js";
|
|
10
10
|
export { SESSION_COOKIE } from "./lookup.js";
|
|
11
|
-
export { signInWithPlaza } from "./plaza.js";
|
|
11
|
+
export { requestPasswordResetWithPlaza, signInWithPlaza } from "./plaza.js";
|
|
12
12
|
/**
|
|
13
13
|
* Cookie attributes the app must use with issueSession's token: inside the platform's App pane the app is a third party, so the
|
|
14
14
|
* cookie must be SameSite=None + Secure + partitioned or the pane signs in
|
package/dist/auth/plaza.d.ts
CHANGED
|
@@ -47,6 +47,14 @@ export type SignInResult = ({
|
|
|
47
47
|
* the session the platform signed for them.
|
|
48
48
|
*/
|
|
49
49
|
export declare function signInWithPlaza(email: string, password: string): Promise<SignInResult>;
|
|
50
|
+
export type PasswordResetResult = {
|
|
51
|
+
readonly ok: true;
|
|
52
|
+
} | {
|
|
53
|
+
readonly ok: false;
|
|
54
|
+
readonly failure: SignInFailure;
|
|
55
|
+
};
|
|
56
|
+
/** `returnTo` is this app's login, where the platform's reset page sends the person afterwards. */
|
|
57
|
+
export declare function requestPasswordResetWithPlaza(email: string, returnTo: string): Promise<PasswordResetResult>;
|
|
50
58
|
/**
|
|
51
59
|
* Spend a code for the person behind it, or null if it is spent or stale.
|
|
52
60
|
*
|
package/dist/auth/plaza.js
CHANGED
|
@@ -45,6 +45,32 @@ export async function signInWithPlaza(email, password) {
|
|
|
45
45
|
failure: failureFor(response.status, await response.text())
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
+
/** `returnTo` is this app's login, where the platform's reset page sends the person afterwards. */
|
|
49
|
+
export async function requestPasswordResetWithPlaza(email, returnTo) {
|
|
50
|
+
const { plazaUrl, appId } = miiAuthConfig();
|
|
51
|
+
let response;
|
|
52
|
+
try {
|
|
53
|
+
response = await fetch(`${plazaUrl}/api/app-auth/request-password-reset`, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: { "Content-Type": "application/json" },
|
|
56
|
+
body: JSON.stringify({ appId, email, returnTo }),
|
|
57
|
+
cache: "no-store"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
return {
|
|
62
|
+
ok: false,
|
|
63
|
+
failure: {
|
|
64
|
+
kind: "unavailable",
|
|
65
|
+
message: "Password reset is unreachable right now. Try again in a moment.",
|
|
66
|
+
cause
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (response.ok)
|
|
71
|
+
return { ok: true };
|
|
72
|
+
return { ok: false, failure: failureFor(response.status, await response.text()) };
|
|
73
|
+
}
|
|
48
74
|
/**
|
|
49
75
|
* Spend a code for the person behind it, or null if it is spent or stale.
|
|
50
76
|
*
|
|
@@ -143,7 +169,7 @@ function failureFor(status, body) {
|
|
|
143
169
|
if (status === 429) {
|
|
144
170
|
return {
|
|
145
171
|
kind: "throttled",
|
|
146
|
-
message: "Too many
|
|
172
|
+
message: "Too many tries. Wait a minute and try again."
|
|
147
173
|
};
|
|
148
174
|
}
|
|
149
175
|
return {
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
// whose functions forget their own guard serves the org's data to anyone.
|
|
4
4
|
/**
|
|
5
5
|
* The template's server functions a signed-out visitor needs to become signed
|
|
6
|
-
* in: who am I, the two ways to sign in, signing out,
|
|
7
|
-
* page renders with.
|
|
6
|
+
* in: who am I, the two ways to sign in, a forgotten password, signing out,
|
|
7
|
+
* and the config the login page renders with.
|
|
8
8
|
*/
|
|
9
9
|
const SIGN_IN_SERVER_FNS = [
|
|
10
10
|
"src/lib/auth.ts#getSessionUser",
|
|
11
11
|
"src/lib/auth.ts#redeemPaneCode",
|
|
12
12
|
"src/lib/auth.ts#loginWithPassword",
|
|
13
|
-
"src/lib/auth.ts#
|
|
13
|
+
"src/lib/auth.ts#requestPasswordReset",
|
|
14
|
+
"src/lib/auth.ts#signOut",
|
|
14
15
|
"src/routes/__root.tsx#getPlatformConfig"
|
|
15
16
|
];
|
|
16
17
|
/**
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
2
|
import { type Contracts } from "../invoke/server.js";
|
|
3
|
-
export type { SessionState, SessionUser, SignIn } from "./session.js";
|
|
3
|
+
export type { PasswordResetRequest, SessionState, SessionUser, SignIn } from "./session.js";
|
|
4
4
|
export { cookieAttributes, safeNext, SESSION_COOKIE } from "../auth/core.js";
|
|
5
5
|
export { defineContracts, InvocationError, type Contracts } from "../invoke/server.js";
|
|
6
6
|
export { createHealthHandler } from "./health.js";
|
|
@@ -15,6 +15,7 @@ export declare function createLightServer<S extends Record<string, unknown>, C e
|
|
|
15
15
|
configured: () => boolean;
|
|
16
16
|
/** Email and password, checked by the platform; the session to set as a cookie, or why not. */
|
|
17
17
|
signIn: (email: string, password: string) => Promise<import("./session.js").SignIn>;
|
|
18
|
+
requestPasswordReset: (email: string, returnTo: string) => Promise<import("./session.js").PasswordResetRequest>;
|
|
18
19
|
/** The app's database, typed by its schema: `light.db.select().from(companies)`. */
|
|
19
20
|
readonly db: PostgresJsDatabase<S>;
|
|
20
21
|
/** `/api/light/entities/*`: what `app.table(...)` calls. */
|
package/dist/server/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { createMiiInvoke } from "../invoke/server.js";
|
|
|
9
9
|
import { createEntitiesHandler } from "./entities.js";
|
|
10
10
|
import { env } from "./env.js";
|
|
11
11
|
import { createImageHandler } from "./images.js";
|
|
12
|
-
import { readSession, signIn } from "./session.js";
|
|
12
|
+
import { readSession, requestPasswordReset, signIn } from "./session.js";
|
|
13
13
|
export { cookieAttributes, safeNext, SESSION_COOKIE } from "../auth/core.js";
|
|
14
14
|
export { defineContracts, InvocationError } from "../invoke/server.js";
|
|
15
15
|
export { createHealthHandler } from "./health.js";
|
|
@@ -38,6 +38,7 @@ export function createLightServer(options) {
|
|
|
38
38
|
configured: () => env().configured,
|
|
39
39
|
/** Email and password, checked by the platform; the session to set as a cookie, or why not. */
|
|
40
40
|
signIn: (email, password) => signIn(auth, email, password),
|
|
41
|
+
requestPasswordReset: (email, returnTo) => requestPasswordReset(email, returnTo),
|
|
41
42
|
/** The app's database, typed by its schema: `light.db.select().from(companies)`. */
|
|
42
43
|
get db() {
|
|
43
44
|
return db();
|
package/dist/server/session.d.ts
CHANGED
|
@@ -16,3 +16,10 @@ export type SignIn = {
|
|
|
16
16
|
};
|
|
17
17
|
/** The login form's whole job: the platform checks the password, the app starts a session. */
|
|
18
18
|
export declare function signIn(auth: MiiAuthCore, email: string, password: string): Promise<SignIn>;
|
|
19
|
+
export type PasswordResetRequest = {
|
|
20
|
+
ok: true;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function requestPasswordReset(email: string, returnTo: string): Promise<PasswordResetRequest>;
|
package/dist/server/session.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Who is asking, as the app's door sees it, and signing in through the platform.
|
|
2
|
-
import { signInWithPlaza } from "../auth/core.js";
|
|
2
|
+
import { requestPasswordResetWithPlaza, signInWithPlaza } from "../auth/core.js";
|
|
3
3
|
import { readCookie } from "../chat/server.js";
|
|
4
4
|
import { env } from "./env.js";
|
|
5
5
|
/** The session a request's cookie names, and whether the app is members-only. */
|
|
@@ -34,3 +34,11 @@ export async function signIn(auth, email, password) {
|
|
|
34
34
|
const session = await auth.issueSession(member.id, result.session);
|
|
35
35
|
return { ok: true, ...session };
|
|
36
36
|
}
|
|
37
|
+
export async function requestPasswordReset(email, returnTo) {
|
|
38
|
+
if (!env().configured)
|
|
39
|
+
return { ok: false, message: "Sign-in is not configured." };
|
|
40
|
+
const result = await requestPasswordResetWithPlaza(email, returnTo);
|
|
41
|
+
if (!result.ok)
|
|
42
|
+
return { ok: false, message: result.failure.message };
|
|
43
|
+
return { ok: true };
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trylight/app",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
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",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"url": "https://github.com/shubh9/mii.git",
|
|
13
13
|
"directory": "packages/app-sdk"
|
|
14
14
|
},
|
|
15
|
-
"packageManager": "pnpm@11.0.9",
|
|
16
15
|
"files": [
|
|
17
16
|
"dist",
|
|
18
17
|
"bin"
|
|
@@ -42,15 +41,6 @@
|
|
|
42
41
|
"default": "./dist/vite.js"
|
|
43
42
|
}
|
|
44
43
|
},
|
|
45
|
-
"scripts": {
|
|
46
|
-
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
47
|
-
"typecheck": "tsc --noEmit",
|
|
48
|
-
"lint": "eslint src test --max-warnings 0",
|
|
49
|
-
"test": "node --test --import tsx \"test/**/*.test.ts\"",
|
|
50
|
-
"check": "tsx scripts/write-brand.ts --check && pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build",
|
|
51
|
-
"prepack": "pnpm run build",
|
|
52
|
-
"brand": "tsx scripts/write-brand.ts"
|
|
53
|
-
},
|
|
54
44
|
"peerDependencies": {
|
|
55
45
|
"@tanstack/react-query": ">=5.69",
|
|
56
46
|
"@tanstack/react-router": ">=1.170",
|
|
@@ -84,5 +74,13 @@
|
|
|
84
74
|
"typescript-eslint": "^8.70.1",
|
|
85
75
|
"vite": "^8.2.0",
|
|
86
76
|
"zod": "^4.6.5"
|
|
77
|
+
},
|
|
78
|
+
"scripts": {
|
|
79
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
80
|
+
"typecheck": "tsc --noEmit",
|
|
81
|
+
"lint": "eslint src test --max-warnings 0",
|
|
82
|
+
"test": "node --test --import tsx \"test/**/*.test.ts\"",
|
|
83
|
+
"check": "tsx scripts/write-brand.ts --check && pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build",
|
|
84
|
+
"brand": "tsx scripts/write-brand.ts"
|
|
87
85
|
}
|
|
88
|
-
}
|
|
86
|
+
}
|