@teamvortexsoftware/vortex-nextjs-15-sdk 0.0.1 → 0.0.3
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/README.md +143 -373
- package/bin/vortex-setup.js +181 -0
- package/dist/config.d.ts +56 -11
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +81 -20
- package/dist/handlers/invitations.js +98 -84
- package/dist/handlers/jwt.d.ts.map +1 -1
- package/dist/handlers/jwt.js +58 -10
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/routes.d.ts +100 -10
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +100 -7
- package/dist/utils.d.ts +5 -5
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +37 -3
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -1,454 +1,224 @@
|
|
|
1
1
|
# Vortex Next.js 15 SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Drop-in Next.js integration for Vortex invitations and JWT functionality. Get up and running in under 2 minutes!
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
**This SDK requires proper security configuration before production use:**
|
|
8
|
-
- ✋ **All invitation endpoints require access control hooks to be configured**
|
|
9
|
-
- ✋ **JWT endpoints require authentication hooks to be configured**
|
|
10
|
-
- ✋ **No endpoints are secured by default - you must implement authorization**
|
|
11
|
-
- ✋ **Input sanitization and rate limiting should be implemented**
|
|
12
|
-
- ✋ **Error messages are sanitized but you should implement proper logging**
|
|
13
|
-
|
|
14
|
-
**This is NOT a drop-in solution - it requires security implementation by you.**
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
5
|
+
## 🚀 Quick Start
|
|
17
6
|
|
|
18
7
|
```bash
|
|
19
|
-
npm install @teamvortexsoftware/vortex-nextjs-15-sdk
|
|
8
|
+
npm install @teamvortexsoftware/vortex-nextjs-15-sdk @teamvortexsoftware/vortex-react-provider
|
|
9
|
+
npx vortex-setup
|
|
20
10
|
```
|
|
21
11
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Configure Vortex in your application:
|
|
25
|
-
|
|
26
|
-
### Environment Variables
|
|
27
|
-
Set the following environment variables:
|
|
28
|
-
```bash
|
|
29
|
-
VORTEX_API_KEY=your_api_key
|
|
30
|
-
VORTEX_API_BASE_URL=https://api.vortexsoftware.com # optional
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Security Configuration (REQUIRED)
|
|
34
|
-
|
|
35
|
-
**CRITICAL**: You MUST configure authentication and access control hooks for ALL endpoints to work securely.
|
|
36
|
-
|
|
37
|
-
#### Complete Security Configuration
|
|
38
|
-
|
|
39
|
-
1. Create a configuration file: `lib/vortex-config.ts`
|
|
40
|
-
```typescript
|
|
41
|
-
import { configureVortex, type AuthenticatedUser, type AccessControlHook } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
42
|
-
import { NextRequest } from 'next/server';
|
|
43
|
-
|
|
44
|
-
configureVortex({
|
|
45
|
-
apiKey: process.env.VORTEX_API_KEY!,
|
|
46
|
-
|
|
47
|
-
// Required for JWT generation
|
|
48
|
-
authenticateUser: async (request: NextRequest): Promise<AuthenticatedUser | null> => {
|
|
49
|
-
// Your authentication logic - get user from session, JWT, etc.
|
|
50
|
-
const user = await getCurrentUser(request);
|
|
51
|
-
|
|
52
|
-
return user ? {
|
|
53
|
-
userId: user.id,
|
|
54
|
-
identifiers: [{ type: 'email', value: user.email }],
|
|
55
|
-
groups: user.groups || [],
|
|
56
|
-
role: user.role
|
|
57
|
-
} : null;
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
// Required for invitation endpoints - implement all that you plan to use
|
|
61
|
-
canAccessInvitationsByTarget: async (request, user, resource) => {
|
|
62
|
-
// Check if user can access invitations for the target
|
|
63
|
-
return user && await canUserAccessTarget(user, resource);
|
|
64
|
-
},
|
|
12
|
+
That's it! The setup wizard creates all required files automatically.
|
|
65
13
|
|
|
66
|
-
|
|
67
|
-
// Check if user can access this specific invitation
|
|
68
|
-
return user && await canUserAccessInvitation(user, resource.invitationId);
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
canDeleteInvitation: async (request, user, resource) => {
|
|
72
|
-
// Check if user can delete this invitation (e.g., admin only)
|
|
73
|
-
return user && user.role === 'admin' && await canUserAccessInvitation(user, resource.invitationId);
|
|
74
|
-
},
|
|
14
|
+
## ⚡ What You Get
|
|
75
15
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
16
|
+
- **JWT Authentication**: Secure user authentication with Vortex
|
|
17
|
+
- **Invitation Management**: Create, accept, and manage invitations
|
|
18
|
+
- **Full Node.js SDK Access**: All `@teamvortexsoftware/vortex-node-22-sdk` functionality
|
|
19
|
+
- **TypeScript Support**: Fully typed with IntelliSense
|
|
20
|
+
- **React Integration**: Works seamlessly with `@teamvortexsoftware/vortex-react-provider`
|
|
80
21
|
|
|
81
|
-
|
|
82
|
-
// Check if user can access invitations for this group
|
|
83
|
-
return user && await canUserAccessGroup(user, resource.groupType, resource.groupId);
|
|
84
|
-
},
|
|
22
|
+
## 📁 Generated Files
|
|
85
23
|
|
|
86
|
-
|
|
87
|
-
// Check if user can delete invitations for this group
|
|
88
|
-
return user && user.role === 'admin' && await canUserAccessGroup(user, resource.groupType, resource.groupId);
|
|
89
|
-
},
|
|
24
|
+
After running `npx vortex-setup`, you'll have:
|
|
90
25
|
|
|
91
|
-
canReinvite: async (request, user, resource) => {
|
|
92
|
-
// Check if user can resend this invitation
|
|
93
|
-
return user && await canUserReinvite(user, resource.invitationId);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
26
|
```
|
|
27
|
+
app/api/vortex/
|
|
28
|
+
├── jwt/route.ts # JWT generation
|
|
29
|
+
├── invitations/route.ts # Get invitations by target
|
|
30
|
+
├── invitations/accept/route.ts # Accept invitations
|
|
31
|
+
├── invitations/[invitationId]/route.ts # Get/delete single invitation
|
|
32
|
+
├── invitations/[invitationId]/reinvite/route.ts # Resend invitation
|
|
33
|
+
└── invitations/by-group/[groupType]/[groupId]/route.ts # Group operations
|
|
97
34
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
2. Import it in your root layout: `app/layout.tsx`
|
|
101
|
-
```typescript
|
|
102
|
-
import '../lib/vortex-config'; // Initialize Vortex configuration
|
|
103
|
-
|
|
104
|
-
export default function RootLayout({ children }) {
|
|
105
|
-
return <html><body>{children}</body></html>;
|
|
106
|
-
}
|
|
35
|
+
lib/
|
|
36
|
+
└── vortex-config.ts # Your configuration
|
|
107
37
|
```
|
|
108
38
|
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
# Just set environment variables
|
|
112
|
-
VORTEX_API_KEY=your_api_key
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
📖 **For detailed configuration options and authentication examples (NextAuth.js, Supabase, custom JWT), see [CONFIGURATION_GUIDE.md](./CONFIGURATION_GUIDE.md)**
|
|
116
|
-
|
|
117
|
-
## Setting Up API Routes
|
|
118
|
-
|
|
119
|
-
This SDK provides convenience functions to create Next.js API route handlers. Create the following files in your Next.js app directory:
|
|
120
|
-
|
|
121
|
-
⚠️ **IMPORTANT - Access Control Required**: The invitation management endpoints do not implement authorization checks. You must add your own access controls to ensure users can only access invitations they are authorized to see. The SDK only handles the Vortex API communication - authorization is your responsibility.
|
|
122
|
-
|
|
123
|
-
### 1. JWT Generation Route
|
|
124
|
-
**File:** `app/api/vortex/jwt/route.ts`
|
|
39
|
+
Each route file is just 3 lines:
|
|
125
40
|
```typescript
|
|
126
|
-
import
|
|
41
|
+
import 'lib/vortex-config';
|
|
42
|
+
import { createVortexRoutes } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
127
43
|
|
|
128
|
-
export const
|
|
44
|
+
export const { GET, DELETE } = createVortexRoutes().invitation;
|
|
129
45
|
```
|
|
130
46
|
|
|
131
|
-
|
|
132
|
-
**File:** `app/api/vortex/invitations/route.ts`
|
|
133
|
-
```typescript
|
|
134
|
-
import { createVortexInvitationsRoute } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
47
|
+
## ⚙️ Configuration
|
|
135
48
|
|
|
136
|
-
|
|
49
|
+
### 1. Environment Variables
|
|
50
|
+
Add to your `.env.local`:
|
|
51
|
+
```bash
|
|
52
|
+
VORTEX_API_KEY=your_api_key_here
|
|
137
53
|
```
|
|
138
54
|
|
|
139
|
-
|
|
55
|
+
### 2. App Layout
|
|
56
|
+
Import the config in your `app/layout.tsx`:
|
|
140
57
|
```typescript
|
|
141
|
-
import
|
|
142
|
-
import { handleGetInvitationsByTarget, createErrorResponse } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
143
|
-
|
|
144
|
-
export async function GET(request: NextRequest) {
|
|
145
|
-
// Add your authorization logic here
|
|
146
|
-
const user = await getCurrentUser(request);
|
|
147
|
-
|
|
148
|
-
if (!user) {
|
|
149
|
-
return createErrorResponse('Unauthorized', 401);
|
|
150
|
-
}
|
|
58
|
+
import '../lib/vortex-config'; // Add this line
|
|
151
59
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
60
|
+
export default function RootLayout({ children }) {
|
|
61
|
+
return (
|
|
62
|
+
<html>
|
|
63
|
+
<body>
|
|
64
|
+
<VortexProvider config={{ apiBaseUrl: '/api/vortex' }}>
|
|
65
|
+
{children}
|
|
66
|
+
</VortexProvider>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|
|
69
|
+
);
|
|
159
70
|
}
|
|
160
71
|
```
|
|
161
72
|
|
|
162
|
-
### 3.
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
import { createVortexInvitationRoute } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
166
|
-
|
|
167
|
-
export const { GET, DELETE } = createVortexInvitationRoute();
|
|
168
|
-
```
|
|
73
|
+
### 3. Customize Configuration
|
|
74
|
+
Edit `lib/vortex-config.ts` to implement your authentication and access control:
|
|
169
75
|
|
|
170
|
-
**With Access Control Example:**
|
|
171
76
|
```typescript
|
|
172
|
-
import {
|
|
173
|
-
import { handleGetInvitation, handleRevokeInvitation, createErrorResponse } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
174
|
-
|
|
175
|
-
export async function GET(request: NextRequest, { params }: { params: { invitationId: string } }) {
|
|
176
|
-
const user = await getCurrentUser(request);
|
|
177
|
-
|
|
178
|
-
if (!user || !await canUserAccessInvitation(user, params.invitationId)) {
|
|
179
|
-
return createErrorResponse('Unauthorized', 401);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return handleGetInvitation(request, params.invitationId);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export async function DELETE(request: NextRequest, { params }: { params: { invitationId: string } }) {
|
|
186
|
-
const user = await getCurrentUser(request);
|
|
77
|
+
import { configureVortexLazy, createAllowAllAccessControl } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
187
78
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return handleRevokeInvitation(request, params.invitationId);
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### 4. Accept Invitations
|
|
197
|
-
**File:** `app/api/vortex/invitations/accept/route.ts`
|
|
198
|
-
```typescript
|
|
199
|
-
import { createVortexInvitationsAcceptRoute } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
200
|
-
|
|
201
|
-
export const { POST } = createVortexInvitationsAcceptRoute();
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### 5. Group-based Invitation Management
|
|
205
|
-
**File:** `app/api/vortex/invitations/by-group/[groupType]/[groupId]/route.ts`
|
|
206
|
-
```typescript
|
|
207
|
-
import { createVortexInvitationsByGroupRoute } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
208
|
-
|
|
209
|
-
export const { GET, DELETE } = createVortexInvitationsByGroupRoute();
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**With Access Control Example:**
|
|
213
|
-
```typescript
|
|
214
|
-
import { NextRequest } from 'next/server';
|
|
215
|
-
import { handleGetInvitationsByGroup, handleDeleteInvitationsByGroup, createErrorResponse } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
216
|
-
|
|
217
|
-
export async function GET(request: NextRequest, { params }: { params: { groupType: string; groupId: string } }) {
|
|
218
|
-
const user = await getCurrentUser(request);
|
|
219
|
-
|
|
220
|
-
if (!user || !await canUserAccessGroup(user, params.groupType, params.groupId)) {
|
|
221
|
-
return createErrorResponse('Unauthorized', 401);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return handleGetInvitationsByGroup(request, params.groupType, params.groupId);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export async function DELETE(request: NextRequest, { params }: { params: { groupType: string; groupId: string } }) {
|
|
228
|
-
const user = await getCurrentUser(request);
|
|
79
|
+
configureVortexLazy(async () => ({
|
|
80
|
+
apiKey: process.env.VORTEX_API_KEY!,
|
|
229
81
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
82
|
+
// Required: How to authenticate users
|
|
83
|
+
authenticateUser: async (request) => {
|
|
84
|
+
const user = await getCurrentUser(request); // Your auth logic
|
|
85
|
+
return user ? {
|
|
86
|
+
userId: user.id,
|
|
87
|
+
identifiers: [{ type: 'email', value: user.email }],
|
|
88
|
+
groups: user.groups, // [{ type: 'team', groupId: '123', name: 'My Team' }]
|
|
89
|
+
} : null;
|
|
90
|
+
},
|
|
233
91
|
|
|
234
|
-
|
|
235
|
-
|
|
92
|
+
// Simple: Allow all operations (customize for production)
|
|
93
|
+
...createAllowAllAccessControl(),
|
|
94
|
+
}));
|
|
236
95
|
```
|
|
237
96
|
|
|
238
|
-
|
|
239
|
-
**File:** `app/api/vortex/invitations/[invitationId]/reinvite/route.ts`
|
|
240
|
-
```typescript
|
|
241
|
-
import { createVortexReinviteRoute } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
97
|
+
## 🔧 Production Security
|
|
242
98
|
|
|
243
|
-
|
|
244
|
-
```
|
|
99
|
+
For production apps, replace `createAllowAllAccessControl()` with proper authorization:
|
|
245
100
|
|
|
246
|
-
**With Access Control Example:**
|
|
247
101
|
```typescript
|
|
248
|
-
|
|
249
|
-
|
|
102
|
+
configureVortexLazy(async () => ({
|
|
103
|
+
apiKey: process.env.VORTEX_API_KEY!,
|
|
104
|
+
authenticateUser: async (request) => { /* your auth */ },
|
|
250
105
|
|
|
251
|
-
|
|
252
|
-
|
|
106
|
+
// Custom access control
|
|
107
|
+
canDeleteInvitation: async (request, user, resource) => {
|
|
108
|
+
return user?.role === 'admin'; // Only admins can delete
|
|
109
|
+
},
|
|
253
110
|
|
|
254
|
-
|
|
255
|
-
return
|
|
256
|
-
|
|
111
|
+
canAccessInvitationsByGroup: async (request, user, resource) => {
|
|
112
|
+
return user?.groups.some(g =>
|
|
113
|
+
g.type === resource?.groupType && g.groupId === resource?.groupId
|
|
114
|
+
);
|
|
115
|
+
},
|
|
257
116
|
|
|
258
|
-
|
|
259
|
-
}
|
|
117
|
+
// ... other access control hooks
|
|
118
|
+
}));
|
|
260
119
|
```
|
|
261
120
|
|
|
262
|
-
## API Endpoints
|
|
263
|
-
|
|
264
|
-
Once set up, your Next.js app will expose the following API endpoints:
|
|
265
|
-
|
|
266
|
-
### JWT Generation
|
|
267
|
-
- **POST** `/api/vortex/jwt`
|
|
268
|
-
- Generates JWT token for the authenticated user making the request
|
|
269
|
-
|
|
270
|
-
**Authentication Required**: This endpoint requires the `authenticateUser` hook to be configured. The JWT will be generated using data from your authenticated user, not from request body data.
|
|
271
|
-
|
|
272
|
-
**Request**: No request body required. User information is obtained through your authentication hook.
|
|
273
|
-
|
|
274
|
-
**Response:**
|
|
275
|
-
```json
|
|
276
|
-
{
|
|
277
|
-
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
278
|
-
}
|
|
279
|
-
```
|
|
121
|
+
## 📚 API Endpoints
|
|
280
122
|
|
|
281
|
-
|
|
282
|
-
- `401 Unauthorized`: User is not authenticated
|
|
283
|
-
- `500 Internal Server Error`: Missing authenticateUser configuration
|
|
123
|
+
Your app automatically gets these API routes:
|
|
284
124
|
|
|
285
|
-
|
|
125
|
+
| Endpoint | Method | Description |
|
|
126
|
+
|----------|--------|-------------|
|
|
127
|
+
| `/api/vortex/jwt` | POST | Generate JWT for authenticated user |
|
|
128
|
+
| `/api/vortex/invitations` | GET | Get invitations by target (email/phone) |
|
|
129
|
+
| `/api/vortex/invitations/accept` | POST | Accept multiple invitations |
|
|
130
|
+
| `/api/vortex/invitations/[id]` | GET/DELETE | Get or delete specific invitation |
|
|
131
|
+
| `/api/vortex/invitations/[id]/reinvite` | POST | Resend invitation |
|
|
132
|
+
| `/api/vortex/invitations/by-group/[type]/[id]` | GET/DELETE | Group-based operations |
|
|
286
133
|
|
|
287
|
-
|
|
288
|
-
- **GET** `/api/vortex/invitations?targetType=email&targetValue=user@example.com`
|
|
289
|
-
- Supported `targetType`: `email`, `username`, `phoneNumber`
|
|
134
|
+
## 🎯 Common Use Cases
|
|
290
135
|
|
|
291
|
-
|
|
292
|
-
|
|
136
|
+
### Frontend: Get User's JWT
|
|
137
|
+
```typescript
|
|
138
|
+
import { useVortexJWT } from '@teamvortexsoftware/vortex-react-provider';
|
|
293
139
|
|
|
294
|
-
|
|
295
|
-
|
|
140
|
+
function MyComponent() {
|
|
141
|
+
const { jwt, isLoading } = useVortexJWT();
|
|
296
142
|
|
|
297
|
-
|
|
298
|
-
|
|
143
|
+
if (isLoading) return <div>Loading...</div>;
|
|
144
|
+
if (!jwt) return <div>Not authenticated</div>;
|
|
299
145
|
|
|
300
|
-
|
|
301
|
-
```json
|
|
302
|
-
{
|
|
303
|
-
"invitationIds": ["inv-123", "inv-456"],
|
|
304
|
-
"target": {
|
|
305
|
-
"type": "email",
|
|
306
|
-
"value": "user@example.com"
|
|
307
|
-
}
|
|
146
|
+
return <div>Authenticated! JWT: {jwt.substring(0, 20)}...</div>;
|
|
308
147
|
}
|
|
309
148
|
```
|
|
310
149
|
|
|
311
|
-
|
|
312
|
-
- **GET** `/api/vortex/invitations/by-group/{groupType}/{groupId}`
|
|
313
|
-
|
|
314
|
-
#### Delete Invitations by Group
|
|
315
|
-
- **DELETE** `/api/vortex/invitations/by-group/{groupType}/{groupId}`
|
|
316
|
-
|
|
317
|
-
#### Resend Invitation
|
|
318
|
-
- **POST** `/api/vortex/invitations/{invitationId}/reinvite`
|
|
319
|
-
|
|
320
|
-
## Advanced Usage
|
|
321
|
-
|
|
322
|
-
### Custom Route Handlers
|
|
323
|
-
If you need more control, you can use the individual handler functions:
|
|
324
|
-
|
|
150
|
+
### Frontend: Manage Invitations
|
|
325
151
|
```typescript
|
|
326
|
-
|
|
327
|
-
import { handleJwtGeneration } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
328
|
-
|
|
329
|
-
export async function POST(request: NextRequest) {
|
|
330
|
-
// Add custom logic here (e.g., authentication, logging)
|
|
152
|
+
const { data: invitations } = useFetch('/api/vortex/invitations/by-group/team/my-team-id');
|
|
331
153
|
|
|
332
|
-
|
|
333
|
-
}
|
|
154
|
+
// Delete invitation
|
|
155
|
+
await fetch(`/api/vortex/invitations/${invitationId}`, { method: 'DELETE' });
|
|
334
156
|
```
|
|
335
157
|
|
|
336
|
-
### Direct SDK
|
|
337
|
-
You can also use the underlying Vortex SDK directly:
|
|
338
|
-
|
|
158
|
+
### Backend: Direct SDK Usage
|
|
339
159
|
```typescript
|
|
340
160
|
import { Vortex } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
341
161
|
|
|
162
|
+
// All Node.js SDK functionality is available
|
|
342
163
|
const vortex = new Vortex(process.env.VORTEX_API_KEY!);
|
|
343
|
-
const
|
|
344
|
-
userId: 'user-123',
|
|
345
|
-
identifiers: [{ type: 'email', value: 'user@example.com' }],
|
|
346
|
-
groups: [{ type: 'org', id: 'org-123', name: 'My Org' }]
|
|
347
|
-
});
|
|
164
|
+
const invitations = await vortex.getInvitationsByGroup('team', 'team-123');
|
|
348
165
|
```
|
|
349
166
|
|
|
350
|
-
##
|
|
351
|
-
|
|
352
|
-
**CRITICAL**: You must implement your own authorization logic for all invitation endpoints. The SDK does not make authorization decisions - it only handles Vortex API communication.
|
|
167
|
+
## 🛠️ Advanced: Custom Routes
|
|
353
168
|
|
|
354
|
-
|
|
169
|
+
Need custom logic? Create your own routes:
|
|
355
170
|
|
|
356
|
-
#### Resource Ownership
|
|
357
171
|
```typescript
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
return invitation && user.organizationIds.includes(invitation.organizationId);
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
#### Role-Based Access
|
|
366
|
-
```typescript
|
|
367
|
-
async function canUserDeleteInvitation(user: any, invitationId: string): Promise<boolean> {
|
|
368
|
-
// Only admins can delete invitations
|
|
369
|
-
return user.role === 'admin' && await canUserAccessInvitation(user, invitationId);
|
|
370
|
-
}
|
|
371
|
-
```
|
|
172
|
+
// app/api/custom-invitation/route.ts
|
|
173
|
+
import 'lib/vortex-config';
|
|
174
|
+
import { handleGetInvitation, createErrorResponse } from '@teamvortexsoftware/vortex-nextjs-15-sdk';
|
|
372
175
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Access Control Checklist
|
|
384
|
-
|
|
385
|
-
For each endpoint, consider:
|
|
386
|
-
- ✅ **Authentication**: Is the user logged in?
|
|
387
|
-
- ✅ **Resource Ownership**: Does the user own or have access to this resource?
|
|
388
|
-
- ✅ **Permission Level**: Does the user have the right permissions for this action?
|
|
389
|
-
- ✅ **Rate Limiting**: Should this endpoint be rate limited?
|
|
390
|
-
- ✅ **Audit Logging**: Should this action be logged?
|
|
391
|
-
|
|
392
|
-
## Error Handling
|
|
393
|
-
|
|
394
|
-
All API routes return standardized error responses:
|
|
176
|
+
export async function GET(request: NextRequest) {
|
|
177
|
+
// Add custom validation
|
|
178
|
+
const user = await validateUser(request);
|
|
179
|
+
if (!user.isAdmin) {
|
|
180
|
+
return createErrorResponse('Admin required', 403);
|
|
181
|
+
}
|
|
395
182
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
"error": "Error message here"
|
|
183
|
+
// Use SDK handler
|
|
184
|
+
return handleGetInvitation(request, 'invitation-id');
|
|
399
185
|
}
|
|
400
186
|
```
|
|
401
187
|
|
|
402
|
-
|
|
403
|
-
- `400`: Bad Request (missing required fields, invalid parameters)
|
|
404
|
-
- `401`: Unauthorized (authentication required)
|
|
405
|
-
- `403`: Forbidden (insufficient permissions)
|
|
406
|
-
- `405`: Method Not Allowed
|
|
407
|
-
- `429`: Too Many Requests (if you implement rate limiting)
|
|
408
|
-
- `500`: Internal Server Error
|
|
409
|
-
|
|
410
|
-
## Rate Limiting & Security Best Practices
|
|
188
|
+
## 🆘 Troubleshooting
|
|
411
189
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
import { Redis } from '@upstash/redis';
|
|
190
|
+
### Build Errors
|
|
191
|
+
If you see configuration errors during build:
|
|
192
|
+
- Make sure you're importing `'lib/vortex-config'` in your layout
|
|
193
|
+
- Check that your `.env.local` has `VORTEX_API_KEY`
|
|
194
|
+
- Ensure you're using lazy initialization (`configureVortexLazy`)
|
|
418
195
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
196
|
+
### Authentication Issues
|
|
197
|
+
- Verify your `authenticateUser` function returns the correct format
|
|
198
|
+
- Check that your authentication provider is working
|
|
199
|
+
- Make sure JWT requests include authentication cookies/headers
|
|
423
200
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
const { success } = await ratelimit.limit(identifier);
|
|
201
|
+
### TypeScript Errors
|
|
202
|
+
- All types are exported from the main package
|
|
203
|
+
- Resource parameters are fully typed for access control hooks
|
|
204
|
+
- Use the generated configuration template as a starting point
|
|
429
205
|
|
|
430
|
-
|
|
431
|
-
return createErrorResponse('Too many requests', 429);
|
|
432
|
-
}
|
|
206
|
+
## 📦 What's Included
|
|
433
207
|
|
|
434
|
-
|
|
435
|
-
return handleGetInvitationsByTarget(request);
|
|
436
|
-
}
|
|
437
|
-
```
|
|
208
|
+
This SDK re-exports everything from `@teamvortexsoftware/vortex-node-22-sdk`, so you get:
|
|
438
209
|
|
|
439
|
-
|
|
440
|
-
- ✅
|
|
441
|
-
- ✅
|
|
442
|
-
- ✅
|
|
443
|
-
- ✅
|
|
444
|
-
- ✅ **Secret management**: Use proper secret storage (not `.env` files in production)
|
|
445
|
-
- ✅ **Monitoring**: Monitor for unusual access patterns
|
|
210
|
+
- ✅ `Vortex` class for direct API access
|
|
211
|
+
- ✅ All invitation management methods
|
|
212
|
+
- ✅ JWT generation utilities
|
|
213
|
+
- ✅ TypeScript definitions
|
|
214
|
+
- ✅ Next.js optimized route handlers
|
|
446
215
|
|
|
447
|
-
##
|
|
216
|
+
## 🔗 Links
|
|
448
217
|
|
|
449
|
-
|
|
218
|
+
- [Node.js SDK Documentation](../vortex-node-22-sdk/README.md)
|
|
219
|
+
- [React Provider Documentation](../vortex-react-provider/README.md)
|
|
220
|
+
- [Example Implementation](../../apps/demo-react)
|
|
450
221
|
|
|
451
|
-
|
|
222
|
+
---
|
|
452
223
|
|
|
453
|
-
|
|
454
|
-
- Node.js 18 or higher
|
|
224
|
+
**Need help?** Open an issue or check the example implementation in `apps/demo-react`.
|