playcademy 0.14.2 → 0.14.4-alpha.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/constants.d.ts +61 -1
- package/dist/constants.js +148 -0
- package/dist/db.js +118 -0
- package/dist/edge-play/src/entry/middleware.ts +102 -5
- package/dist/edge-play/src/entry/session.ts +44 -0
- package/dist/edge-play/src/entry.ts +33 -1
- package/dist/edge-play/src/index.ts +3 -1
- package/dist/edge-play/src/register-routes.ts +0 -4
- package/dist/edge-play/src/types.ts +7 -5
- package/dist/index.d.ts +122 -90
- package/dist/index.js +2658 -1751
- package/dist/templates/api/sample-protected.ts.template +34 -0
- package/dist/templates/auth/auth-catch-all.ts.template +18 -0
- package/dist/templates/auth/auth-schema.ts.template +62 -0
- package/dist/templates/auth/auth.ts.template +55 -0
- package/dist/templates/config/integrations-config.js.template +1 -1
- package/dist/templates/playcademy-env.d.ts.template +12 -3
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +760 -1029
- package/dist/version.d.ts +3 -0
- package/dist/version.js +82 -0
- package/package.json +6 -2
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { User } from '../../lib/auth'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Protected Route Example
|
|
5
|
+
*
|
|
6
|
+
* Demonstrates how to require authentication in a route.
|
|
7
|
+
* This endpoint will only be accessible to authenticated users.
|
|
8
|
+
*/
|
|
9
|
+
export async function GET(c: Context): Promise<Response> {
|
|
10
|
+
// Check if user is authenticated
|
|
11
|
+
const user = c.get('user') as User | undefined
|
|
12
|
+
|
|
13
|
+
if (!user) {
|
|
14
|
+
return c.json({ error: 'Authentication required' }, 401)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// OPTIONAL: Require user to be from Playcademy platform
|
|
18
|
+
// Useful for platform-exclusive features
|
|
19
|
+
// if (!user.playcademyUserId) {
|
|
20
|
+
// return c.json({ error: 'Platform access required' }, 403)
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
return c.json({
|
|
24
|
+
success: true,
|
|
25
|
+
message: 'Authentication working! You are signed in.',
|
|
26
|
+
user: {
|
|
27
|
+
id: user.id,
|
|
28
|
+
email: user.email,
|
|
29
|
+
name: user.name,
|
|
30
|
+
playcademyUserId: user.playcademyUserId,
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Better Auth Routes
|
|
3
|
+
*
|
|
4
|
+
* Handles all Better Auth routes (/api/auth/*)
|
|
5
|
+
* This is a standard catch-all route - no customization needed.
|
|
6
|
+
*/
|
|
7
|
+
import { getAuth } from '../../lib/auth'
|
|
8
|
+
|
|
9
|
+
export async function GET(c: Context): Promise<Response> {
|
|
10
|
+
const auth = getAuth(c)
|
|
11
|
+
return auth.handler(c.req.raw)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function POST(c: Context): Promise<Response> {
|
|
15
|
+
const auth = getAuth(c)
|
|
16
|
+
return auth.handler(c.req.raw)
|
|
17
|
+
}
|
|
18
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Better Auth Schema
|
|
3
|
+
*
|
|
4
|
+
* Database tables for Better Auth authentication system
|
|
5
|
+
*/
|
|
6
|
+
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
|
|
7
|
+
|
|
8
|
+
export const user = sqliteTable('user', {
|
|
9
|
+
id: text('id').primaryKey(),
|
|
10
|
+
name: text('name').notNull(),
|
|
11
|
+
email: text('email').notNull().unique(),
|
|
12
|
+
emailVerified: integer('emailVerified').notNull(),
|
|
13
|
+
image: text('image'),
|
|
14
|
+
createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
|
|
15
|
+
updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
|
|
16
|
+
|
|
17
|
+
// Platform linkage: Links this user to a Playcademy platform identity
|
|
18
|
+
// When users launch the game from Playcademy, their platform identity
|
|
19
|
+
// is verified and linked to a Better Auth session via this field
|
|
20
|
+
playcademyUserId: text('playcademy_user_id').unique(),
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export const session = sqliteTable('session', {
|
|
24
|
+
id: text('id').primaryKey(),
|
|
25
|
+
expiresAt: integer('expiresAt', { mode: 'timestamp' }).notNull(),
|
|
26
|
+
token: text('token').notNull().unique(),
|
|
27
|
+
createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
|
|
28
|
+
updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
|
|
29
|
+
ipAddress: text('ipAddress'),
|
|
30
|
+
userAgent: text('userAgent'),
|
|
31
|
+
userId: text('userId')
|
|
32
|
+
.notNull()
|
|
33
|
+
.references(() => user.id, { onDelete: 'cascade' }),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export const account = sqliteTable('account', {
|
|
37
|
+
id: text('id').primaryKey(),
|
|
38
|
+
accountId: text('accountId').notNull(),
|
|
39
|
+
providerId: text('providerId').notNull(),
|
|
40
|
+
userId: text('userId')
|
|
41
|
+
.notNull()
|
|
42
|
+
.references(() => user.id, { onDelete: 'cascade' }),
|
|
43
|
+
accessToken: text('accessToken'),
|
|
44
|
+
refreshToken: text('refreshToken'),
|
|
45
|
+
idToken: text('idToken'),
|
|
46
|
+
accessTokenExpiresAt: integer('accessTokenExpiresAt', { mode: 'timestamp' }),
|
|
47
|
+
refreshTokenExpiresAt: integer('refreshTokenExpiresAt', { mode: 'timestamp' }),
|
|
48
|
+
scope: text('scope'),
|
|
49
|
+
password: text('password'),
|
|
50
|
+
createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
|
|
51
|
+
updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
export const verification = sqliteTable('verification', {
|
|
55
|
+
id: text('id').primaryKey(),
|
|
56
|
+
identifier: text('identifier').notNull(),
|
|
57
|
+
value: text('value').notNull(),
|
|
58
|
+
expiresAt: integer('expiresAt', { mode: 'timestamp' }).notNull(),
|
|
59
|
+
createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
|
|
60
|
+
updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
|
|
61
|
+
})
|
|
62
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Better Auth Configuration
|
|
3
|
+
*
|
|
4
|
+
* CUSTOMIZABLE: This file is where you configure your auth providers,
|
|
5
|
+
* social logins, and other auth-specific settings.
|
|
6
|
+
*/
|
|
7
|
+
import { betterAuth } from 'better-auth'
|
|
8
|
+
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
|
|
9
|
+
|
|
10
|
+
import { playcademy } from '@playcademy/better-auth/server'
|
|
11
|
+
|
|
12
|
+
import { getDb } from '../../db'
|
|
13
|
+
|
|
14
|
+
import type { Context } from 'hono'
|
|
15
|
+
|
|
16
|
+
export function getAuth(c: Context) {
|
|
17
|
+
const db = getDb(c.env.DB)
|
|
18
|
+
|
|
19
|
+
// CUSTOMIZABLE: Configure trusted origins for CORS
|
|
20
|
+
// These origins are allowed to make cross-origin requests to your game's auth endpoints.
|
|
21
|
+
// Add your deployed game URLs here when you deploy to staging or production.
|
|
22
|
+
const trustedOrigins = [
|
|
23
|
+
'http://localhost:5173', // Local development
|
|
24
|
+
// 'https://{{GAME_SLUG}}-staging.playcademy.gg', // Staging deployment
|
|
25
|
+
// 'https://{{GAME_SLUG}}.playcademy.gg', // Production deployment
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
return betterAuth({
|
|
29
|
+
database: drizzleAdapter(db, {
|
|
30
|
+
provider: 'sqlite',
|
|
31
|
+
usePlural: false,
|
|
32
|
+
}),
|
|
33
|
+
|
|
34
|
+
trustedOrigins,
|
|
35
|
+
{{EMAIL_AND_PASSWORD}}{{SOCIAL_PROVIDERS}}
|
|
36
|
+
// REQUIRED: Platform integration
|
|
37
|
+
plugins: [
|
|
38
|
+
playcademy(),
|
|
39
|
+
],
|
|
40
|
+
|
|
41
|
+
// CUSTOMIZABLE: Cookie settings
|
|
42
|
+
advanced: {
|
|
43
|
+
defaultCookieAttributes: {
|
|
44
|
+
path: '/',
|
|
45
|
+
secure: true,
|
|
46
|
+
partitioned: true, // CHIPS for Chrome/Edge
|
|
47
|
+
sameSite: 'none', // Ensure state + session cookies are sent on cross-site redirects
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type Auth = ReturnType<typeof getAuth>
|
|
54
|
+
export type Session = Auth['$Infer']['Session']
|
|
55
|
+
export type User = Auth['$Infer']['Session']['user']
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playcademy Environment Types
|
|
3
|
+
*
|
|
4
|
+
* Auto-generated by Playcademy CLI.
|
|
5
|
+
* Regenerated on: playcademy dev, playcademy init, playcademy db init, playcademy auth init
|
|
6
|
+
*
|
|
7
|
+
* Do not edit - changes will be overwritten.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
/// <reference types="./.playcademy/node_modules/@cloudflare/workers-types" />
|
|
2
11
|
|
|
3
|
-
import type { Context as HonoContext } from './.playcademy/node_modules/hono'
|
|
12
|
+
import type { Context as HonoContext } from './.playcademy/node_modules/hono'{{AUTH_IMPORT}}
|
|
4
13
|
|
|
5
14
|
declare global {
|
|
6
15
|
interface PlaycademyEnv {
|
|
7
16
|
PLAYCADEMY_API_KEY: string
|
|
8
17
|
GAME_ID: string
|
|
9
18
|
PLAYCADEMY_BASE_URL: string{{BINDINGS}}{{SECRETS}}
|
|
10
|
-
}
|
|
19
|
+
}{{VARIABLES}}
|
|
11
20
|
|
|
12
|
-
type Context = HonoContext<{ Bindings: PlaycademyEnv }>
|
|
21
|
+
type Context = HonoContext<{ Bindings: PlaycademyEnv{{CONTEXT_VARS}} }>
|
|
13
22
|
}
|
|
14
23
|
|
|
15
24
|
export {}
|
package/dist/utils.d.ts
CHANGED
|
@@ -54,6 +54,8 @@ interface IntegrationsConfig {
|
|
|
54
54
|
kv?: boolean;
|
|
55
55
|
/** Bucket storage (optional) */
|
|
56
56
|
bucket?: boolean;
|
|
57
|
+
/** Authentication (optional) */
|
|
58
|
+
auth?: boolean;
|
|
57
59
|
}
|
|
58
60
|
/**
|
|
59
61
|
* Unified Playcademy configuration
|
|
@@ -80,6 +82,14 @@ interface PlaycademyConfig {
|
|
|
80
82
|
integrations?: IntegrationsConfig;
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Logger interface for embedding in other tools (e.g., vite plugin)
|
|
87
|
+
*/
|
|
88
|
+
interface PluginLogger {
|
|
89
|
+
info: (msg: string) => void;
|
|
90
|
+
warn: (msg: string) => void;
|
|
91
|
+
error: (msg: string) => void;
|
|
92
|
+
}
|
|
83
93
|
interface DevServerOptions {
|
|
84
94
|
port: number;
|
|
85
95
|
/** Playcademy config. If not provided, will attempt to load from playcademy.config.js */
|
|
@@ -94,6 +104,8 @@ interface DevServerOptions {
|
|
|
94
104
|
onReload?: (restart: () => Promise<void>) => void;
|
|
95
105
|
/** URL for Playcademy platform/sandbox API (defaults to localhost:5174 platform) */
|
|
96
106
|
platformUrl?: string;
|
|
107
|
+
/** Custom logger for embedding (e.g., from vite plugin) */
|
|
108
|
+
customLogger?: PluginLogger;
|
|
97
109
|
}
|
|
98
110
|
|
|
99
111
|
/**
|