@shubh90/app-runtime 0.2.1 → 0.3.0

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.
@@ -0,0 +1,66 @@
1
+ import { getAuthMode } from "./mode.js";
2
+ import { safeNext } from "./next-path.js";
3
+ import { SIGN_IN_PROBLEMS } from "./problems.js";
4
+ import { type MiiUser } from "./lookup.js";
5
+ import { type MiiIdentity } from "./plaza.js";
6
+ import { type UsersConfig } from "./users-config.js";
7
+ export type { MiiUser } from "./lookup.js";
8
+ export type { AuthMode } from "./mode.js";
9
+ export type { MiiIdentity, SignInFailure, SignInResult } from "./plaza.js";
10
+ export type { UsersConfig } from "./users-config.js";
11
+ export { SIGN_IN_PROBLEMS } from "./problems.js";
12
+ export { safeNext } from "./next-path.js";
13
+ export { getAuthMode } from "./mode.js";
14
+ export { SESSION_COOKIE, SESSION_TTL_MS } from "./lookup.js";
15
+ export { miiAuthConfig, type MiiAuthConfig } from "./config.js";
16
+ export { redeemWithPlaza, signInWithPlaza } from "./plaza.js";
17
+ export type CreateMiiAuthCoreOptions = {
18
+ /** Which table holds this app's people, if not the default `mii_auth_users`. */
19
+ readonly users?: UsersConfig;
20
+ /** Where to report failures that are ours, not the person's. Defaults to console.error. */
21
+ readonly reportError?: (error: unknown, context: Record<string, string>) => void;
22
+ };
23
+ export type MiiAuthCore = {
24
+ /** The user behind a session token, or null. The app reads its own cookie. */
25
+ resolveSession(token: string): Promise<MiiUser | null>;
26
+ /** Start a session; the app sets the cookie itself (see cookie notes below). */
27
+ issueSession(userId: string): Promise<{
28
+ token: string;
29
+ expiresAt: Date;
30
+ }>;
31
+ /** End one session by its token. */
32
+ revokeSession(token: string): Promise<void>;
33
+ upsertMemberFromIdentity(identity: MiiIdentity): Promise<{
34
+ id: string;
35
+ status: string;
36
+ }>;
37
+ deactivateUser(userId: string): Promise<void>;
38
+ /**
39
+ * The pane's silent sign-in: spend a ?mii_code= for an identity, upsert the
40
+ * member, start a session. Null when the code is spent/stale or the member
41
+ * is inactive (send them to /login).
42
+ */
43
+ redeemPaneCode(code: string): Promise<{
44
+ token: string;
45
+ expiresAt: Date;
46
+ } | null>;
47
+ getAuthMode: typeof getAuthMode;
48
+ readonly SESSION_COOKIE: string;
49
+ readonly SIGN_IN_PROBLEMS: typeof SIGN_IN_PROBLEMS;
50
+ readonly safeNext: typeof safeNext;
51
+ };
52
+ /**
53
+ * Cookie attributes the app must use with issueSession's token, mirrored from
54
+ * the Next adapter: inside Plaza's App pane the app is a third party, so the
55
+ * cookie must be SameSite=None + Secure + partitioned or the pane signs in
56
+ * forever; opened directly it is an ordinary Lax cookie. Decide by the
57
+ * request's `Sec-Fetch-Dest: iframe` header.
58
+ */
59
+ export declare function cookieAttributes(embedded: boolean): {
60
+ httpOnly: true;
61
+ path: "/";
62
+ sameSite: "none" | "lax";
63
+ secure: boolean;
64
+ partitioned: boolean;
65
+ };
66
+ export declare function createMiiAuthCore(options?: CreateMiiAuthCoreOptions): MiiAuthCore;
@@ -0,0 +1,62 @@
1
+ import { makeAuthSql } from "./db.js";
2
+ import { getAuthMode } from "./mode.js";
3
+ import { safeNext } from "./next-path.js";
4
+ import { SIGN_IN_PROBLEMS } from "./problems.js";
5
+ import { issueSession, resolveSession, SESSION_COOKIE, SESSION_TTL_MS, hashToken } from "./lookup.js";
6
+ import { redeemWithPlaza } from "./plaza.js";
7
+ import { deactivateUser, upsertMemberFromIdentity } from "./users.js";
8
+ import { resolveUsers } from "./users-config.js";
9
+ export { SIGN_IN_PROBLEMS } from "./problems.js";
10
+ export { safeNext } from "./next-path.js";
11
+ export { getAuthMode } from "./mode.js";
12
+ export { SESSION_COOKIE, SESSION_TTL_MS } from "./lookup.js";
13
+ export { miiAuthConfig } from "./config.js";
14
+ export { redeemWithPlaza, signInWithPlaza } from "./plaza.js";
15
+ /**
16
+ * Cookie attributes the app must use with issueSession's token, mirrored from
17
+ * the Next adapter: inside Plaza's App pane the app is a third party, so the
18
+ * cookie must be SameSite=None + Secure + partitioned or the pane signs in
19
+ * forever; opened directly it is an ordinary Lax cookie. Decide by the
20
+ * request's `Sec-Fetch-Dest: iframe` header.
21
+ */
22
+ export function cookieAttributes(embedded) {
23
+ return {
24
+ httpOnly: true,
25
+ path: "/",
26
+ sameSite: embedded ? "none" : "lax",
27
+ secure: embedded || process.env.NODE_ENV === "production",
28
+ partitioned: embedded
29
+ };
30
+ }
31
+ export function createMiiAuthCore(options = {}) {
32
+ const users = resolveUsers(options.users);
33
+ const ctx = {
34
+ getSql: makeAuthSql(users),
35
+ users,
36
+ reportError: options.reportError ??
37
+ ((error, context) => console.error("mii-auth error", context, error))
38
+ };
39
+ return {
40
+ resolveSession: (token) => resolveSession(ctx, token),
41
+ issueSession: (userId) => issueSession(ctx, userId),
42
+ revokeSession: async (token) => {
43
+ const sql = await ctx.getSql();
44
+ await sql `delete from mii_auth_sessions where token_hash = ${hashToken(token)}`;
45
+ },
46
+ upsertMemberFromIdentity: (identity) => upsertMemberFromIdentity(ctx, identity),
47
+ deactivateUser: (userId) => deactivateUser(ctx, userId),
48
+ redeemPaneCode: async (code) => {
49
+ const identity = await redeemWithPlaza(code);
50
+ if (identity === null)
51
+ return null;
52
+ const user = await upsertMemberFromIdentity(ctx, identity);
53
+ if (user.status !== "active")
54
+ return null;
55
+ return issueSession(ctx, user.id);
56
+ },
57
+ getAuthMode,
58
+ SESSION_COOKIE,
59
+ SIGN_IN_PROBLEMS,
60
+ safeNext
61
+ };
62
+ }
@@ -10,6 +10,7 @@ export type { MiiIdentity } from "./plaza.js";
10
10
  export type { UsersConfig } from "./users-config.js";
11
11
  export { SIGN_IN_PROBLEMS } from "./problems.js";
12
12
  export { safeNext } from "./next-path.js";
13
+ export { getAuthMode } from "./mode.js";
13
14
  export { SESSION_COOKIE } from "./lookup.js";
14
15
  export { miiAuthConfig, type MiiAuthConfig } from "./config.js";
15
16
  export { redeemWithPlaza, signInWithPlaza, type SignInFailure, type SignInResult } from "./plaza.js";
@@ -10,6 +10,7 @@ import { deactivateUser, upsertMemberFromIdentity } from "./users.js";
10
10
  import { resolveUsers } from "./users-config.js";
11
11
  export { SIGN_IN_PROBLEMS } from "./problems.js";
12
12
  export { safeNext } from "./next-path.js";
13
+ export { getAuthMode } from "./mode.js";
13
14
  export { SESSION_COOKIE } from "./lookup.js";
14
15
  // Unbound pieces (no user-table context): the app's own proxy and login page
15
16
  // may use these directly, the way the template's do.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shubh90/app-runtime",
3
- "version": "0.2.1",
4
- "description": "The platform contract every mii org app depends on \u2014 sign-in, and the Next.js config an app must not diverge from. A versioned package, not files copied into each repo.",
3
+ "version": "0.3.0",
4
+ "description": "The platform contract every mii org app depends on sign-in, and the Next.js config an app must not diverge from. A versioned package, not files copied into each repo.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "publishConfig": {
@@ -20,6 +20,10 @@
20
20
  "types": "./dist/auth/index.d.ts",
21
21
  "import": "./dist/auth/index.js"
22
22
  },
23
+ "./auth/core": {
24
+ "types": "./dist/auth/core.d.ts",
25
+ "import": "./dist/auth/core.js"
26
+ },
23
27
  "./next": {
24
28
  "types": "./dist/next/index.d.ts",
25
29
  "import": "./dist/next/index.js"
@@ -35,6 +39,11 @@
35
39
  "next": ">=15",
36
40
  "postgres": ">=3"
37
41
  },
42
+ "peerDependenciesMeta": {
43
+ "next": {
44
+ "optional": true
45
+ }
46
+ },
38
47
  "devDependencies": {
39
48
  "@types/node": "^22",
40
49
  "next": "^15",