oauth.do 0.2.0 → 0.2.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.
@@ -0,0 +1,114 @@
1
+ // src/session.ts
2
+ var defaultSessionConfig = {
3
+ cookieName: "session",
4
+ cookieMaxAge: 60 * 60 * 24 * 7,
5
+ // 7 days
6
+ cookieSecure: true,
7
+ cookieSameSite: "lax",
8
+ secret: "oauth-do-dev-secret-change-in-production"
9
+ };
10
+ var ALGORITHM = "AES-GCM";
11
+ var IV_LENGTH = 12;
12
+ var TAG_LENGTH = 128;
13
+ async function getEncryptionKey(secret) {
14
+ const encoder = new TextEncoder();
15
+ return crypto.subtle.importKey(
16
+ "raw",
17
+ encoder.encode(secret.padEnd(32, "0").slice(0, 32)),
18
+ { name: ALGORITHM },
19
+ false,
20
+ ["encrypt", "decrypt"]
21
+ );
22
+ }
23
+ async function encodeSession(session, secret) {
24
+ const key = await getEncryptionKey(secret ?? defaultSessionConfig.secret);
25
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
26
+ const encoder = new TextEncoder();
27
+ const data = encoder.encode(JSON.stringify(session));
28
+ const ciphertext = await crypto.subtle.encrypt(
29
+ { name: ALGORITHM, iv, tagLength: TAG_LENGTH },
30
+ key,
31
+ data
32
+ );
33
+ const combined = new Uint8Array(iv.length + ciphertext.byteLength);
34
+ combined.set(iv, 0);
35
+ combined.set(new Uint8Array(ciphertext), iv.length);
36
+ return btoa(String.fromCharCode(...combined));
37
+ }
38
+ async function decodeSession(encoded, secret) {
39
+ try {
40
+ const key = await getEncryptionKey(secret ?? defaultSessionConfig.secret);
41
+ const combined = Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
42
+ const iv = combined.slice(0, IV_LENGTH);
43
+ const ciphertext = combined.slice(IV_LENGTH);
44
+ const decrypted = await crypto.subtle.decrypt(
45
+ { name: ALGORITHM, iv, tagLength: TAG_LENGTH },
46
+ key,
47
+ ciphertext
48
+ );
49
+ const decoder = new TextDecoder();
50
+ const parsed = JSON.parse(decoder.decode(decrypted));
51
+ if (!isValidSessionData(parsed)) {
52
+ return null;
53
+ }
54
+ return parsed;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+ function isValidSessionData(data) {
60
+ if (data === null || typeof data !== "object") {
61
+ return false;
62
+ }
63
+ const session = data;
64
+ if (typeof session.userId !== "string" || session.userId.length === 0) {
65
+ return false;
66
+ }
67
+ if (typeof session.accessToken !== "string" || session.accessToken.length === 0) {
68
+ return false;
69
+ }
70
+ if (session.organizationId !== void 0 && typeof session.organizationId !== "string") {
71
+ return false;
72
+ }
73
+ if (session.email !== void 0 && typeof session.email !== "string") {
74
+ return false;
75
+ }
76
+ if (session.name !== void 0 && typeof session.name !== "string") {
77
+ return false;
78
+ }
79
+ if (session.refreshToken !== void 0 && typeof session.refreshToken !== "string") {
80
+ return false;
81
+ }
82
+ if (session.expiresAt !== void 0 && typeof session.expiresAt !== "number") {
83
+ return false;
84
+ }
85
+ return true;
86
+ }
87
+ function getSessionConfig(env) {
88
+ const validSameSite = ["strict", "lax", "none"];
89
+ let cookieSameSite = defaultSessionConfig.cookieSameSite;
90
+ if (env?.SESSION_COOKIE_SAME_SITE) {
91
+ const value = env.SESSION_COOKIE_SAME_SITE;
92
+ if (validSameSite.includes(value)) {
93
+ cookieSameSite = value;
94
+ }
95
+ }
96
+ let cookieMaxAge = defaultSessionConfig.cookieMaxAge;
97
+ if (env?.SESSION_COOKIE_MAX_AGE) {
98
+ const parsed = parseInt(env.SESSION_COOKIE_MAX_AGE, 10);
99
+ if (!Number.isNaN(parsed) && parsed > 0) {
100
+ cookieMaxAge = parsed;
101
+ }
102
+ }
103
+ return {
104
+ secret: env?.SESSION_SECRET ?? defaultSessionConfig.secret,
105
+ cookieName: env?.SESSION_COOKIE_NAME ?? defaultSessionConfig.cookieName,
106
+ cookieMaxAge,
107
+ cookieSecure: env?.SESSION_COOKIE_SECURE !== "false",
108
+ cookieSameSite
109
+ };
110
+ }
111
+
112
+ export { decodeSession, defaultSessionConfig, encodeSession, getSessionConfig, isValidSessionData };
113
+ //# sourceMappingURL=session.js.map
114
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session.ts"],"names":[],"mappings":"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","file":"session.js","sourcesContent":["/**\n * oauth.do/session - Cookie-based session management with AES-GCM encryption\n *\n * Secure session encoding/decoding using Web Crypto API.\n * Zero dependencies - works in all environments that support Web Crypto.\n *\n * @example\n * ```ts\n * import { encodeSession, decodeSession } from 'oauth.do/session'\n *\n * const session = { userId: 'user_123', accessToken: 'tok_abc' }\n * const encoded = await encodeSession(session, 'my-secret-key')\n * const decoded = await decodeSession(encoded, 'my-secret-key')\n * ```\n */\n\n// ─────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Session data stored in encrypted cookie\n */\nexport interface SessionData {\n userId: string\n organizationId?: string\n email?: string\n name?: string\n accessToken: string\n refreshToken?: string\n expiresAt?: number\n /** Extensible: apps can add custom fields */\n [key: string]: unknown\n}\n\n/**\n * Configuration for session management\n */\nexport interface SessionConfig {\n /** Cookie name (default: 'session') */\n cookieName: string\n /** Cookie max age in seconds (default: 604800 = 7 days) */\n cookieMaxAge: number\n /** Cookie secure flag (default: true) */\n cookieSecure: boolean\n /** Cookie SameSite attribute (default: 'lax') */\n cookieSameSite: 'strict' | 'lax' | 'none'\n /** Encryption secret (required in production) */\n secret: string\n}\n\n/**\n * Default session configuration\n */\nexport const defaultSessionConfig: SessionConfig = {\n cookieName: 'session',\n cookieMaxAge: 60 * 60 * 24 * 7, // 7 days\n cookieSecure: true,\n cookieSameSite: 'lax',\n secret: 'oauth-do-dev-secret-change-in-production',\n}\n\n// ─────────────────────────────────────────────────────────────────\n// AES-GCM Encryption\n// ─────────────────────────────────────────────────────────────────\n\nconst ALGORITHM = 'AES-GCM'\nconst IV_LENGTH = 12\nconst TAG_LENGTH = 128\n\n/**\n * Derive an AES-GCM encryption key from a secret string\n */\nasync function getEncryptionKey(secret: string): Promise<CryptoKey> {\n const encoder = new TextEncoder()\n return crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret.padEnd(32, '0').slice(0, 32)),\n { name: ALGORITHM },\n false,\n ['encrypt', 'decrypt']\n )\n}\n\n/**\n * Encode session data with AES-GCM encryption.\n * Format: base64(IV || ciphertext || auth tag)\n *\n * @param session - Session data to encrypt\n * @param secret - Encryption secret (min 16 chars recommended)\n * @returns Base64-encoded encrypted session string\n */\nexport async function encodeSession(session: SessionData, secret?: string): Promise<string> {\n const key = await getEncryptionKey(secret ?? defaultSessionConfig.secret)\n const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH))\n const encoder = new TextEncoder()\n const data = encoder.encode(JSON.stringify(session))\n\n const ciphertext = await crypto.subtle.encrypt(\n { name: ALGORITHM, iv, tagLength: TAG_LENGTH },\n key,\n data\n )\n\n // Combine IV + ciphertext (ciphertext includes auth tag)\n const combined = new Uint8Array(iv.length + ciphertext.byteLength)\n combined.set(iv, 0)\n combined.set(new Uint8Array(ciphertext), iv.length)\n\n return btoa(String.fromCharCode(...combined))\n}\n\n/**\n * Decode session data with AES-GCM decryption.\n * Returns null if decryption fails or data is invalid.\n *\n * @param encoded - Base64-encoded encrypted session string\n * @param secret - Encryption secret (must match the one used for encoding)\n * @returns Decoded session data or null\n */\nexport async function decodeSession(encoded: string, secret?: string): Promise<SessionData | null> {\n try {\n const key = await getEncryptionKey(secret ?? defaultSessionConfig.secret)\n const combined = Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0))\n\n const iv = combined.slice(0, IV_LENGTH)\n const ciphertext = combined.slice(IV_LENGTH)\n\n const decrypted = await crypto.subtle.decrypt(\n { name: ALGORITHM, iv, tagLength: TAG_LENGTH },\n key,\n ciphertext\n )\n\n const decoder = new TextDecoder()\n const parsed: unknown = JSON.parse(decoder.decode(decrypted))\n\n if (!isValidSessionData(parsed)) {\n return null\n }\n\n return parsed\n } catch {\n return null\n }\n}\n\n/**\n * Validate that session data has the required structure\n */\nexport function isValidSessionData(data: unknown): data is SessionData {\n if (data === null || typeof data !== 'object') {\n return false\n }\n\n const session = data as Record<string, unknown>\n\n // Required fields\n if (typeof session.userId !== 'string' || session.userId.length === 0) {\n return false\n }\n if (typeof session.accessToken !== 'string' || session.accessToken.length === 0) {\n return false\n }\n\n // Optional fields type validation\n if (session.organizationId !== undefined && typeof session.organizationId !== 'string') {\n return false\n }\n if (session.email !== undefined && typeof session.email !== 'string') {\n return false\n }\n if (session.name !== undefined && typeof session.name !== 'string') {\n return false\n }\n if (session.refreshToken !== undefined && typeof session.refreshToken !== 'string') {\n return false\n }\n if (session.expiresAt !== undefined && typeof session.expiresAt !== 'number') {\n return false\n }\n\n return true\n}\n\n/**\n * Get session config from environment variables with defaults.\n *\n * Environment variables:\n * - SESSION_SECRET: Encryption secret\n * - SESSION_COOKIE_NAME: Cookie name\n * - SESSION_COOKIE_MAX_AGE: Cookie max age in seconds\n * - SESSION_COOKIE_SECURE: 'true' or 'false'\n * - SESSION_COOKIE_SAME_SITE: 'strict', 'lax', or 'none'\n */\nexport function getSessionConfig(env?: Record<string, string | undefined>): SessionConfig {\n const validSameSite = ['strict', 'lax', 'none'] as const\n\n let cookieSameSite: SessionConfig['cookieSameSite'] = defaultSessionConfig.cookieSameSite\n if (env?.SESSION_COOKIE_SAME_SITE) {\n const value = env.SESSION_COOKIE_SAME_SITE\n if (validSameSite.includes(value as typeof validSameSite[number])) {\n cookieSameSite = value as SessionConfig['cookieSameSite']\n }\n }\n\n let cookieMaxAge = defaultSessionConfig.cookieMaxAge\n if (env?.SESSION_COOKIE_MAX_AGE) {\n const parsed = parseInt(env.SESSION_COOKIE_MAX_AGE, 10)\n if (!Number.isNaN(parsed) && parsed > 0) {\n cookieMaxAge = parsed\n }\n }\n\n return {\n secret: env?.SESSION_SECRET ?? defaultSessionConfig.secret,\n cookieName: env?.SESSION_COOKIE_NAME ?? defaultSessionConfig.cookieName,\n cookieMaxAge,\n cookieSecure: env?.SESSION_COOKIE_SECURE !== 'false',\n cookieSameSite,\n }\n}\n"]}
package/package.json CHANGED
@@ -1,150 +1,152 @@
1
1
  {
2
- "name": "oauth.do",
3
- "version": "0.2.0",
4
- "description": "OAuth authentication SDK, React components, and Hono middleware for org.ai identity",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "bin": {
9
- "oauth.do": "./dist/cli.js",
10
- "duckdb-auth": "./bin/duckdb-auth"
11
- },
12
- "exports": {
13
- ".": {
14
- "types": "./dist/index.d.ts",
15
- "import": "./dist/index.js",
16
- "require": "./dist/index.js",
17
- "default": "./dist/index.js"
18
- },
19
- "./node": {
20
- "types": "./dist/node.d.ts",
21
- "import": "./dist/node.js",
22
- "require": "./dist/node.js",
23
- "default": "./dist/node.js"
24
- },
25
- "./react": {
26
- "types": "./dist/react.d.ts",
27
- "import": "./dist/react.js",
28
- "require": "./dist/react.js",
29
- "default": "./dist/react.js"
30
- },
31
- "./hono": {
32
- "types": "./dist/hono.d.ts",
33
- "import": "./dist/hono.js",
34
- "require": "./dist/hono.js",
35
- "default": "./dist/hono.js"
36
- },
37
- "./types": {
38
- "types": "./dist/types-export.d.ts",
39
- "import": "./dist/types-export.js"
40
- },
41
- "./mdx/*": "./src/mdx/*"
42
- },
43
- "files": [
44
- "dist",
45
- "bin",
46
- "src/mdx",
47
- "README.md",
48
- "LICENSE"
49
- ],
50
- "scripts": {
51
- "build": "tsup",
52
- "dev": "tsup --watch",
53
- "test": "vitest run",
54
- "test:watch": "vitest",
55
- "check:publish": "node -e \"const pkg = require('./package.json'); const deps = JSON.stringify(pkg.dependencies || {}); if (deps.includes('workspace:')) { console.error('ERROR: workspace: protocol found in dependencies. Replace with actual versions before publishing.'); process.exit(1); }\"",
56
- "prepublishOnly": "pnpm check:publish && pnpm build && pnpm test"
57
- },
58
- "keywords": [
59
- "oauth",
60
- "authentication",
61
- "auth",
62
- "login",
63
- "identity",
64
- "cli",
65
- "sdk",
66
- "org-ai",
67
- "workos",
68
- "authkit",
69
- "react",
70
- "hono"
71
- ],
72
- "author": {
73
- "name": "org.ai",
74
- "email": "npm@org.ai",
75
- "url": "https://org.ai"
76
- },
77
- "license": "MIT",
78
- "repository": {
79
- "type": "git",
80
- "url": "git+https://github.com/dot-do/oauth.do.git"
81
- },
82
- "bugs": {
83
- "url": "https://github.com/dot-do/oauth.do/issues"
84
- },
85
- "homepage": "https://oauth.do",
86
- "engines": {
87
- "node": ">=18.0.0"
88
- },
89
- "dependencies": {
90
- "open": "^10.1.0"
91
- },
92
- "optionalDependencies": {
93
- "keytar": "^7.9.0"
94
- },
95
- "peerDependencies": {
96
- "@radix-ui/themes": ">=3.0.0",
97
- "@tanstack/react-query": ">=5.0.0",
98
- "@workos-inc/authkit-react": ">=0.5.0",
99
- "@workos-inc/widgets": ">=1.0.0",
100
- "hono": ">=4.0.0",
101
- "jose": ">=5.0.0",
102
- "react": ">=18.0.0",
103
- "react-dom": ">=18.0.0"
104
- },
105
- "peerDependenciesMeta": {
106
- "@radix-ui/themes": {
107
- "optional": true
108
- },
109
- "@tanstack/react-query": {
110
- "optional": true
111
- },
112
- "@workos-inc/authkit-react": {
113
- "optional": true
114
- },
115
- "@workos-inc/widgets": {
116
- "optional": true
117
- },
118
- "hono": {
119
- "optional": true
120
- },
121
- "jose": {
122
- "optional": true
123
- },
124
- "react": {
125
- "optional": true
126
- },
127
- "react-dom": {
128
- "optional": true
129
- }
130
- },
131
- "devDependencies": {
132
- "@radix-ui/themes": "^3.0.0",
133
- "@tanstack/react-query": "^5.0.0",
134
- "@testing-library/jest-dom": "^6.9.1",
135
- "@testing-library/react": "^16.3.2",
136
- "@types/node": "^24.10.1",
137
- "@types/react": "^18.2.0",
138
- "@types/react-dom": "^18.2.0",
139
- "@workos-inc/authkit-react": "^0.16.0",
140
- "@workos-inc/widgets": "^1.0.0",
141
- "hono": "^4.0.0",
142
- "jose": "^5.0.0",
143
- "jsdom": "^27.4.0",
144
- "react": "^18.2.0",
145
- "react-dom": "^18.2.0",
146
- "tsup": "^8.0.0",
147
- "typescript": "^5.5.2",
148
- "vitest": "^2.1.8"
149
- }
2
+ "name": "oauth.do",
3
+ "version": "0.2.2",
4
+ "description": "OAuth authentication SDK, React components, and Hono middleware for org.ai identity",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "oauth.do": "./dist/cli.js",
10
+ "duckdb-auth": "./bin/duckdb-auth"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./node": {
20
+ "types": "./dist/node.d.ts",
21
+ "import": "./dist/node.js",
22
+ "require": "./dist/node.js",
23
+ "default": "./dist/node.js"
24
+ },
25
+ "./react": {
26
+ "types": "./dist/react.d.ts",
27
+ "import": "./dist/react.js",
28
+ "require": "./dist/react.js",
29
+ "default": "./dist/react.js"
30
+ },
31
+ "./hono": {
32
+ "types": "./dist/hono.d.ts",
33
+ "import": "./dist/hono.js",
34
+ "require": "./dist/hono.js",
35
+ "default": "./dist/hono.js"
36
+ },
37
+ "./types": {
38
+ "types": "./dist/types-export.d.ts",
39
+ "import": "./dist/types-export.js"
40
+ },
41
+ "./session": {
42
+ "types": "./dist/session.d.ts",
43
+ "import": "./dist/session.js"
44
+ },
45
+ "./mdx/*": "./src/mdx/*"
46
+ },
47
+ "files": [
48
+ "dist",
49
+ "bin",
50
+ "src/mdx",
51
+ "README.md",
52
+ "LICENSE"
53
+ ],
54
+ "scripts": {
55
+ "build": "tsup",
56
+ "dev": "tsup --watch",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest",
59
+ "check:publish": "node -e \"const pkg = require('./package.json'); const deps = JSON.stringify(pkg.dependencies || {}); if (deps.includes('workspace:')) { console.error('ERROR: workspace: protocol found in dependencies. Replace with actual versions before publishing.'); process.exit(1); }\"",
60
+ "prepublishOnly": "pnpm check:publish && pnpm build && pnpm test"
61
+ },
62
+ "keywords": [
63
+ "oauth",
64
+ "authentication",
65
+ "auth",
66
+ "login",
67
+ "identity",
68
+ "cli",
69
+ "sdk",
70
+ "org-ai",
71
+ "workos",
72
+ "authkit",
73
+ "react",
74
+ "hono"
75
+ ],
76
+ "author": {
77
+ "name": "org.ai",
78
+ "email": "npm@org.ai",
79
+ "url": "https://org.ai"
80
+ },
81
+ "license": "MIT",
82
+ "repository": {
83
+ "type": "git",
84
+ "url": "git+https://github.com/dot-do/oauth.do.git"
85
+ },
86
+ "bugs": {
87
+ "url": "https://github.com/dot-do/oauth.do/issues"
88
+ },
89
+ "homepage": "https://oauth.do",
90
+ "engines": {
91
+ "node": ">=18.0.0"
92
+ },
93
+ "dependencies": {
94
+ "open": "^10.1.0",
95
+ "keytar": "^7.9.0"
96
+ },
97
+ "peerDependencies": {
98
+ "@radix-ui/themes": ">=3.0.0",
99
+ "@tanstack/react-query": ">=5.0.0",
100
+ "@workos-inc/authkit-react": ">=0.5.0",
101
+ "@workos-inc/widgets": ">=1.0.0",
102
+ "hono": ">=4.0.0",
103
+ "jose": ">=5.0.0",
104
+ "react": ">=18.0.0",
105
+ "react-dom": ">=18.0.0"
106
+ },
107
+ "peerDependenciesMeta": {
108
+ "@radix-ui/themes": {
109
+ "optional": true
110
+ },
111
+ "@tanstack/react-query": {
112
+ "optional": true
113
+ },
114
+ "@workos-inc/authkit-react": {
115
+ "optional": true
116
+ },
117
+ "@workos-inc/widgets": {
118
+ "optional": true
119
+ },
120
+ "hono": {
121
+ "optional": true
122
+ },
123
+ "jose": {
124
+ "optional": true
125
+ },
126
+ "react": {
127
+ "optional": true
128
+ },
129
+ "react-dom": {
130
+ "optional": true
131
+ }
132
+ },
133
+ "devDependencies": {
134
+ "@radix-ui/themes": "^3.0.0",
135
+ "@tanstack/react-query": "^5.0.0",
136
+ "@testing-library/jest-dom": "^6.9.1",
137
+ "@testing-library/react": "^16.3.2",
138
+ "@types/node": "^24.10.1",
139
+ "@types/react": "^18.2.0",
140
+ "@types/react-dom": "^18.2.0",
141
+ "@workos-inc/authkit-react": "^0.16.0",
142
+ "@workos-inc/widgets": "^1.0.0",
143
+ "hono": "^4.0.0",
144
+ "jose": "^5.0.0",
145
+ "jsdom": "^27.4.0",
146
+ "react": "^18.2.0",
147
+ "react-dom": "^18.2.0",
148
+ "tsup": "^8.0.0",
149
+ "typescript": "^5.5.2",
150
+ "vitest": "^2.1.8"
151
+ }
150
152
  }