@jhits/plugin-users 0.0.12 → 0.0.14
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/api/bridge.d.ts +28 -0
- package/dist/api/bridge.d.ts.map +1 -0
- package/dist/api/bridge.js +85 -0
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +16 -23
- package/dist/index.server.d.ts +1 -0
- package/dist/index.server.d.ts.map +1 -1
- package/dist/index.server.js +1 -0
- package/package.json +2 -2
- package/src/api/bridge.ts +98 -0
- package/src/api/router.ts +16 -30
- package/src/index.server.ts +1 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Users - Session Bridge API
|
|
3
|
+
* Handles cross-domain session transfer via secure one-time tokens
|
|
4
|
+
*/
|
|
5
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
6
|
+
/**
|
|
7
|
+
* GET /api/plugin-users/bridge/generate - Generate a one-time transfer token
|
|
8
|
+
* Call this from the "Primary" domain (.com)
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateTransferToken(req: NextRequest, config: any): Promise<NextResponse<{
|
|
11
|
+
error: string;
|
|
12
|
+
}> | NextResponse<{
|
|
13
|
+
token: string;
|
|
14
|
+
}>>;
|
|
15
|
+
/**
|
|
16
|
+
* GET /api/plugin-users/bridge/verify - Verify a transfer token and return user data
|
|
17
|
+
* Call this from the "Target" domain (.nl, .se) via proxy
|
|
18
|
+
*/
|
|
19
|
+
export declare function verifyTransferToken(req: NextRequest, config: any): Promise<NextResponse<{
|
|
20
|
+
error: string;
|
|
21
|
+
}> | NextResponse<{
|
|
22
|
+
id: any;
|
|
23
|
+
email: any;
|
|
24
|
+
name: any;
|
|
25
|
+
role: any;
|
|
26
|
+
image: any;
|
|
27
|
+
}>>;
|
|
28
|
+
//# sourceMappingURL=bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/api/bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgBxD;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG;;;;IAwBxE;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG;;;;;;;;IA0CtE"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Users - Session Bridge API
|
|
3
|
+
* Handles cross-domain session transfer via secure one-time tokens
|
|
4
|
+
*/
|
|
5
|
+
import { NextResponse } from 'next/server';
|
|
6
|
+
import { getToken } from 'next-auth/jwt';
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
// Token store (in-memory for simplicity, as tokens are extremely short-lived)
|
|
9
|
+
// In a large multi-server setup, this should be in Redis
|
|
10
|
+
const tokenStore = new Map();
|
|
11
|
+
// Cleanup expired tokens periodically
|
|
12
|
+
setInterval(() => {
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
for (const [token, data] of tokenStore.entries()) {
|
|
15
|
+
if (data.expires < now)
|
|
16
|
+
tokenStore.delete(token);
|
|
17
|
+
}
|
|
18
|
+
}, 60000);
|
|
19
|
+
/**
|
|
20
|
+
* GET /api/plugin-users/bridge/generate - Generate a one-time transfer token
|
|
21
|
+
* Call this from the "Primary" domain (.com)
|
|
22
|
+
*/
|
|
23
|
+
export async function generateTransferToken(req, config) {
|
|
24
|
+
try {
|
|
25
|
+
const token = await getToken({
|
|
26
|
+
req,
|
|
27
|
+
secret: process.env.NEXTAUTH_SECRET || config.jwtSecret
|
|
28
|
+
});
|
|
29
|
+
if (!token || !token.sub) {
|
|
30
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
31
|
+
}
|
|
32
|
+
const transferToken = randomBytes(32).toString('hex');
|
|
33
|
+
const expires = Date.now() + 30000; // 30 seconds expiry
|
|
34
|
+
tokenStore.set(transferToken, {
|
|
35
|
+
userId: token.sub,
|
|
36
|
+
expires
|
|
37
|
+
});
|
|
38
|
+
return NextResponse.json({ token: transferToken });
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error('[BridgeAPI] Generate error:', err);
|
|
42
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* GET /api/plugin-users/bridge/verify - Verify a transfer token and return user data
|
|
47
|
+
* Call this from the "Target" domain (.nl, .se) via proxy
|
|
48
|
+
*/
|
|
49
|
+
export async function verifyTransferToken(req, config) {
|
|
50
|
+
try {
|
|
51
|
+
const url = new URL(req.url);
|
|
52
|
+
const transferToken = url.searchParams.get('token');
|
|
53
|
+
if (!transferToken) {
|
|
54
|
+
return NextResponse.json({ error: 'Token required' }, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
const data = tokenStore.get(transferToken);
|
|
57
|
+
if (!data || data.expires < Date.now()) {
|
|
58
|
+
tokenStore.delete(transferToken);
|
|
59
|
+
return NextResponse.json({ error: 'Invalid or expired token' }, { status: 401 });
|
|
60
|
+
}
|
|
61
|
+
// Token used, remove it
|
|
62
|
+
tokenStore.delete(transferToken);
|
|
63
|
+
// Fetch user data
|
|
64
|
+
const dbConnection = await config.getDb();
|
|
65
|
+
const db = dbConnection.db();
|
|
66
|
+
const { ObjectId } = require('mongodb');
|
|
67
|
+
const user = await db.collection('users').findOne({
|
|
68
|
+
_id: new ObjectId(data.userId)
|
|
69
|
+
});
|
|
70
|
+
if (!user) {
|
|
71
|
+
return NextResponse.json({ error: 'User not found' }, { status: 404 });
|
|
72
|
+
}
|
|
73
|
+
return NextResponse.json({
|
|
74
|
+
id: user._id.toString(),
|
|
75
|
+
email: user.email,
|
|
76
|
+
name: user.name,
|
|
77
|
+
role: user.role || 'user',
|
|
78
|
+
image: user.image || null
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
console.error('[BridgeAPI] Verify error:', err);
|
|
83
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
|
84
|
+
}
|
|
85
|
+
}
|
package/dist/api/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/api/router.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAIzC;;;;GAIG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,cAAc,GACvB,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/api/router.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAIzC;;;;GAIG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,cAAc,GACvB,OAAO,CAAC,YAAY,CAAC,CA2DvB"}
|
package/dist/api/router.js
CHANGED
|
@@ -25,52 +25,45 @@ export async function handleUsersApi(req, path, config) {
|
|
|
25
25
|
initAuthHandler(config.authOptions);
|
|
26
26
|
}
|
|
27
27
|
// Route: /api/auth/[...nextauth] - NextAuth routes
|
|
28
|
-
// When routed from /api/auth, the path contains the nextauth segments
|
|
29
|
-
// Path structure: /api/auth/session -> path: ['session']
|
|
30
|
-
// Path structure: /api/auth/signin -> path: ['signin']
|
|
31
|
-
// Path structure: /api/auth -> path: [] (empty)
|
|
32
|
-
// We handle this by checking if route is empty (root /api/auth) or if it's a known NextAuth route
|
|
33
28
|
const isNextAuthRoute = route === '' ||
|
|
34
29
|
['session', 'signin', 'signout', 'callback', 'csrf', 'providers', 'error'].includes(route);
|
|
35
30
|
if (isNextAuthRoute) {
|
|
36
|
-
// This is a NextAuth route - use the path as nextauth segments
|
|
37
|
-
// For /api/auth, path is [] -> nextauthPath is []
|
|
38
|
-
// For /api/auth/session, path is ['session'] -> nextauthPath is ['session']
|
|
39
31
|
const nextauthPath = path;
|
|
40
|
-
// Create NextAuth context
|
|
41
32
|
const nextauthContext = {
|
|
42
33
|
params: Promise.resolve({ nextauth: nextauthPath })
|
|
43
34
|
};
|
|
44
|
-
if (method === 'GET')
|
|
35
|
+
if (method === 'GET')
|
|
45
36
|
return await AuthGET(req, nextauthContext);
|
|
46
|
-
|
|
47
|
-
if (method === 'POST') {
|
|
37
|
+
if (method === 'POST')
|
|
48
38
|
return await AuthPOST(req, nextauthContext);
|
|
39
|
+
}
|
|
40
|
+
// Route: /api/plugin-users/bridge (Session Bridge)
|
|
41
|
+
if (route === 'bridge') {
|
|
42
|
+
const bridgeModule = await import('./bridge');
|
|
43
|
+
const subRoute = path.length > 1 ? path[1] : '';
|
|
44
|
+
if (subRoute === 'generate' && method === 'GET') {
|
|
45
|
+
return await bridgeModule.generateTransferToken(req, config);
|
|
46
|
+
}
|
|
47
|
+
if (subRoute === 'verify' && method === 'GET') {
|
|
48
|
+
return await bridgeModule.verifyTransferToken(req, config);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
// Route: /api/users or /api/plugin-users/users (user management)
|
|
52
52
|
if (route === 'users') {
|
|
53
53
|
if (path.length === 1) {
|
|
54
|
-
|
|
55
|
-
if (method === 'GET') {
|
|
54
|
+
if (method === 'GET')
|
|
56
55
|
return await GET_USERS(req, config);
|
|
57
|
-
|
|
58
|
-
if (method === 'POST') {
|
|
56
|
+
if (method === 'POST')
|
|
59
57
|
return await POST_USERS(req, config);
|
|
60
|
-
}
|
|
61
58
|
}
|
|
62
59
|
else if (path.length === 2) {
|
|
63
|
-
// /api/users/[id] or /api/plugin-users/users/[id]
|
|
64
60
|
const userId = path[1];
|
|
65
|
-
if (method === 'PATCH')
|
|
61
|
+
if (method === 'PATCH')
|
|
66
62
|
return await PATCH_USER(req, userId, config);
|
|
67
|
-
|
|
68
|
-
if (method === 'DELETE') {
|
|
63
|
+
if (method === 'DELETE')
|
|
69
64
|
return await DELETE_USER(req, userId, config);
|
|
70
|
-
}
|
|
71
65
|
}
|
|
72
66
|
}
|
|
73
|
-
// Method not allowed
|
|
74
67
|
return NextResponse.json({ error: `Method ${method} not allowed for route: ${route || '/'}` }, { status: 405 });
|
|
75
68
|
}
|
|
76
69
|
catch (error) {
|
package/dist/index.server.d.ts
CHANGED
|
@@ -8,5 +8,6 @@ import 'server-only';
|
|
|
8
8
|
*/
|
|
9
9
|
export { handleUsersApi as handleApi } from './api/router';
|
|
10
10
|
export { handleUsersApi } from './api/router';
|
|
11
|
+
export { generateTransferToken, verifyTransferToken } from './api/bridge';
|
|
11
12
|
export type { UsersApiConfig } from './api/users';
|
|
12
13
|
//# sourceMappingURL=index.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.server.d.ts","sourceRoot":"","sources":["../src/index.server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,IAAI,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.server.d.ts","sourceRoot":"","sources":["../src/index.server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,IAAI,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jhits/plugin-users",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "User management and authentication plugin for the JHITS ecosystem",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@types/node": "^25.2.3",
|
|
37
37
|
"@types/react": "^19.2.14",
|
|
38
38
|
"@types/react-dom": "^19.2.3",
|
|
39
|
-
"@jhits/plugin-core": "0.0.
|
|
39
|
+
"@jhits/plugin-core": "0.0.10"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"next": ">=15.0.0",
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Users - Session Bridge API
|
|
3
|
+
* Handles cross-domain session transfer via secure one-time tokens
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
7
|
+
import { getToken } from 'next-auth/jwt';
|
|
8
|
+
import { randomBytes, createHmac } from 'crypto';
|
|
9
|
+
|
|
10
|
+
// Token store (in-memory for simplicity, as tokens are extremely short-lived)
|
|
11
|
+
// In a large multi-server setup, this should be in Redis
|
|
12
|
+
const tokenStore = new Map<string, { userId: string; expires: number }>();
|
|
13
|
+
|
|
14
|
+
// Cleanup expired tokens periodically
|
|
15
|
+
setInterval(() => {
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
for (const [token, data] of tokenStore.entries()) {
|
|
18
|
+
if (data.expires < now) tokenStore.delete(token);
|
|
19
|
+
}
|
|
20
|
+
}, 60000);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* GET /api/plugin-users/bridge/generate - Generate a one-time transfer token
|
|
24
|
+
* Call this from the "Primary" domain (.com)
|
|
25
|
+
*/
|
|
26
|
+
export async function generateTransferToken(req: NextRequest, config: any) {
|
|
27
|
+
try {
|
|
28
|
+
const token = await getToken({
|
|
29
|
+
req,
|
|
30
|
+
secret: process.env.NEXTAUTH_SECRET || config.jwtSecret
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (!token || !token.sub) {
|
|
34
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const transferToken = randomBytes(32).toString('hex');
|
|
38
|
+
const expires = Date.now() + 30000; // 30 seconds expiry
|
|
39
|
+
|
|
40
|
+
tokenStore.set(transferToken, {
|
|
41
|
+
userId: token.sub,
|
|
42
|
+
expires
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return NextResponse.json({ token: transferToken });
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.error('[BridgeAPI] Generate error:', err);
|
|
48
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* GET /api/plugin-users/bridge/verify - Verify a transfer token and return user data
|
|
54
|
+
* Call this from the "Target" domain (.nl, .se) via proxy
|
|
55
|
+
*/
|
|
56
|
+
export async function verifyTransferToken(req: NextRequest, config: any) {
|
|
57
|
+
try {
|
|
58
|
+
const url = new URL(req.url);
|
|
59
|
+
const transferToken = url.searchParams.get('token');
|
|
60
|
+
|
|
61
|
+
if (!transferToken) {
|
|
62
|
+
return NextResponse.json({ error: 'Token required' }, { status: 400 });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const data = tokenStore.get(transferToken);
|
|
66
|
+
if (!data || data.expires < Date.now()) {
|
|
67
|
+
tokenStore.delete(transferToken);
|
|
68
|
+
return NextResponse.json({ error: 'Invalid or expired token' }, { status: 401 });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Token used, remove it
|
|
72
|
+
tokenStore.delete(transferToken);
|
|
73
|
+
|
|
74
|
+
// Fetch user data
|
|
75
|
+
const dbConnection = await config.getDb();
|
|
76
|
+
const db = dbConnection.db();
|
|
77
|
+
const { ObjectId } = require('mongodb');
|
|
78
|
+
|
|
79
|
+
const user = await db.collection('users').findOne({
|
|
80
|
+
_id: new ObjectId(data.userId)
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (!user) {
|
|
84
|
+
return NextResponse.json({ error: 'User not found' }, { status: 404 });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return NextResponse.json({
|
|
88
|
+
id: user._id.toString(),
|
|
89
|
+
email: user.email,
|
|
90
|
+
name: user.name,
|
|
91
|
+
role: user.role || 'user',
|
|
92
|
+
image: user.image || null
|
|
93
|
+
});
|
|
94
|
+
} catch (err) {
|
|
95
|
+
console.error('[BridgeAPI] Verify error:', err);
|
|
96
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
|
97
|
+
}
|
|
98
|
+
}
|
package/src/api/router.ts
CHANGED
|
@@ -35,56 +35,43 @@ export async function handleUsersApi(
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// Route: /api/auth/[...nextauth] - NextAuth routes
|
|
38
|
-
// When routed from /api/auth, the path contains the nextauth segments
|
|
39
|
-
// Path structure: /api/auth/session -> path: ['session']
|
|
40
|
-
// Path structure: /api/auth/signin -> path: ['signin']
|
|
41
|
-
// Path structure: /api/auth -> path: [] (empty)
|
|
42
|
-
// We handle this by checking if route is empty (root /api/auth) or if it's a known NextAuth route
|
|
43
38
|
const isNextAuthRoute = route === '' ||
|
|
44
39
|
['session', 'signin', 'signout', 'callback', 'csrf', 'providers', 'error'].includes(route);
|
|
45
40
|
|
|
46
41
|
if (isNextAuthRoute) {
|
|
47
|
-
// This is a NextAuth route - use the path as nextauth segments
|
|
48
|
-
// For /api/auth, path is [] -> nextauthPath is []
|
|
49
|
-
// For /api/auth/session, path is ['session'] -> nextauthPath is ['session']
|
|
50
42
|
const nextauthPath = path;
|
|
51
|
-
|
|
52
|
-
// Create NextAuth context
|
|
53
43
|
const nextauthContext = {
|
|
54
44
|
params: Promise.resolve({ nextauth: nextauthPath })
|
|
55
45
|
};
|
|
56
46
|
|
|
57
|
-
if (method === 'GET')
|
|
58
|
-
|
|
47
|
+
if (method === 'GET') return await AuthGET(req, nextauthContext);
|
|
48
|
+
if (method === 'POST') return await AuthPOST(req, nextauthContext);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Route: /api/plugin-users/bridge (Session Bridge)
|
|
52
|
+
if (route === 'bridge') {
|
|
53
|
+
const bridgeModule = await import('./bridge');
|
|
54
|
+
const subRoute = path.length > 1 ? path[1] : '';
|
|
55
|
+
if (subRoute === 'generate' && method === 'GET') {
|
|
56
|
+
return await bridgeModule.generateTransferToken(req, config);
|
|
59
57
|
}
|
|
60
|
-
if (method === '
|
|
61
|
-
return await
|
|
58
|
+
if (subRoute === 'verify' && method === 'GET') {
|
|
59
|
+
return await bridgeModule.verifyTransferToken(req, config);
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
// Route: /api/users or /api/plugin-users/users (user management)
|
|
66
64
|
if (route === 'users') {
|
|
67
65
|
if (path.length === 1) {
|
|
68
|
-
|
|
69
|
-
if (method === '
|
|
70
|
-
return await GET_USERS(req, config);
|
|
71
|
-
}
|
|
72
|
-
if (method === 'POST') {
|
|
73
|
-
return await POST_USERS(req, config);
|
|
74
|
-
}
|
|
66
|
+
if (method === 'GET') return await GET_USERS(req, config);
|
|
67
|
+
if (method === 'POST') return await POST_USERS(req, config);
|
|
75
68
|
} else if (path.length === 2) {
|
|
76
|
-
// /api/users/[id] or /api/plugin-users/users/[id]
|
|
77
69
|
const userId = path[1];
|
|
78
|
-
if (method === 'PATCH')
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
if (method === 'DELETE') {
|
|
82
|
-
return await DELETE_USER(req, userId, config);
|
|
83
|
-
}
|
|
70
|
+
if (method === 'PATCH') return await PATCH_USER(req, userId, config);
|
|
71
|
+
if (method === 'DELETE') return await DELETE_USER(req, userId, config);
|
|
84
72
|
}
|
|
85
73
|
}
|
|
86
74
|
|
|
87
|
-
// Method not allowed
|
|
88
75
|
return NextResponse.json(
|
|
89
76
|
{ error: `Method ${method} not allowed for route: ${route || '/'}` },
|
|
90
77
|
{ status: 405 }
|
|
@@ -97,4 +84,3 @@ export async function handleUsersApi(
|
|
|
97
84
|
);
|
|
98
85
|
}
|
|
99
86
|
}
|
|
100
|
-
|
package/src/index.server.ts
CHANGED
|
@@ -10,5 +10,6 @@ import 'server-only';
|
|
|
10
10
|
|
|
11
11
|
export { handleUsersApi as handleApi } from './api/router';
|
|
12
12
|
export { handleUsersApi } from './api/router'; // Keep original export for backward compatibility
|
|
13
|
+
export { generateTransferToken, verifyTransferToken } from './api/bridge';
|
|
13
14
|
export type { UsersApiConfig } from './api/users';
|
|
14
15
|
|