@shubh90/app-runtime 0.2.2 → 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.
- package/dist/auth/core.d.ts +66 -0
- package/dist/auth/core.js +62 -0
- package/package.json +11 -2
|
@@ -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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shubh90/app-runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The platform contract every mii org app depends on
|
|
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",
|