@nextsparkjs/core 0.1.0-beta.196 → 0.1.0-beta.197
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 +2 -0
- package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
- package/dist/components/auth/forms/SignupForm.js +55 -45
- package/dist/components/dashboard/block-editor/config-panel.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/config-panel.js +3 -2
- package/dist/components/dashboard/block-editor/entity-fields-sidebar.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/entity-fields-sidebar.js +3 -2
- package/dist/components/users/tables/UsersTable.d.ts.map +1 -1
- package/dist/components/users/tables/UsersTable.js +3 -4
- package/dist/hooks/useAuthReadiness.d.ts +1 -0
- package/dist/hooks/useAuthReadiness.d.ts.map +1 -1
- package/dist/hooks/useAuthReadiness.js +3 -1
- package/dist/lib/actions/entity.actions.js +2 -2
- package/dist/lib/actions/team.actions.js +2 -2
- package/dist/lib/actions/user.actions.js +4 -4
- package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
- package/dist/lib/api/auth/dual-auth.js +3 -2
- package/dist/lib/api/auth.d.ts.map +1 -1
- package/dist/lib/api/auth.js +7 -0
- package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
- package/dist/lib/api/entity/generic-handler.js +66 -12
- package/dist/lib/api/entity-handler.js +2 -2
- package/dist/lib/api/helpers.d.ts.map +1 -1
- package/dist/lib/api/helpers.js +4 -2
- package/dist/lib/api/post-categories.d.ts +29 -0
- package/dist/lib/api/post-categories.d.ts.map +1 -0
- package/dist/lib/api/post-categories.js +33 -0
- package/dist/lib/auth/auth-methods.d.ts +5 -2
- package/dist/lib/auth/auth-methods.d.ts.map +1 -1
- package/dist/lib/auth/auth-methods.js +4 -2
- package/dist/lib/auth/authorization-session.d.ts +14 -0
- package/dist/lib/auth/authorization-session.d.ts.map +1 -0
- package/dist/lib/auth/authorization-session.js +10 -0
- package/dist/lib/auth/request-session.d.ts +5 -0
- package/dist/lib/auth/request-session.d.ts.map +1 -1
- package/dist/lib/auth/request-session.js +3 -0
- package/dist/lib/auth/runtime-readiness.d.ts +7 -4
- package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
- package/dist/lib/auth/runtime-readiness.js +7 -6
- package/dist/lib/auth/sample-accounts.d.ts +2 -1
- package/dist/lib/auth/sample-accounts.d.ts.map +1 -1
- package/dist/lib/auth/sample-accounts.js +4 -1
- package/dist/lib/auth/suspension.d.ts +22 -0
- package/dist/lib/auth/suspension.d.ts.map +1 -0
- package/dist/lib/auth/suspension.js +43 -0
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +15 -15
- package/dist/lib/config/app.config.d.ts.map +1 -1
- package/dist/lib/config/app.config.js +6 -7
- package/dist/lib/config/types.d.ts +8 -6
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/db-pool.d.ts +31 -0
- package/dist/lib/db-pool.d.ts.map +1 -0
- package/dist/lib/db-pool.js +75 -0
- package/dist/lib/db.d.ts +1 -1
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +11 -14
- package/dist/lib/entities/api-generator.js +5 -5
- package/dist/lib/oauth/token-refresh.d.ts.map +1 -1
- package/dist/lib/oauth/token-refresh.js +3 -6
- package/dist/lib/permissions/check.d.ts +9 -0
- package/dist/lib/permissions/check.d.ts.map +1 -1
- package/dist/lib/permissions/check.js +11 -1
- package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
- package/dist/lib/services/generic-entity.service.js +39 -7
- package/dist/lib/services/transactional-meta.service.d.ts.map +1 -1
- package/dist/lib/services/transactional-meta.service.js +7 -8
- package/dist/lib/validation.d.ts +5 -0
- package/dist/lib/validation.d.ts.map +1 -1
- package/dist/lib/validation.js +2 -0
- package/dist/migrations/030_taxonomies_team_writes.sql +29 -0
- package/dist/migrations/031_users_role_suspended.sql +41 -0
- package/dist/routes/(auth)/signup/page.cc.d.ts +3 -1
- package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
- package/dist/routes/(auth)/signup/page.cc.js +2 -2
- package/dist/routes/(auth)/signup/page.d.ts +3 -1
- package/dist/routes/(auth)/signup/page.d.ts.map +1 -1
- package/dist/routes/(auth)/signup/page.js +4 -3
- package/dist/routes/_internal/area-access.js +2 -2
- package/dist/routes/api/devtools/config/entities/route.js +2 -2
- package/dist/routes/api/devtools/config/theme/route.js +2 -2
- package/dist/routes/api/devtools/tests/[...path]/route.js +2 -2
- package/dist/routes/api/devtools/tests/route.js +2 -2
- package/dist/routes/api/superadmin/subscriptions/route.js +2 -2
- package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -2
- package/dist/routes/api/superadmin/teams/route.js +2 -2
- package/dist/routes/api/superadmin/users/[userId]/route.d.ts +5 -3
- package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
- package/dist/routes/api/superadmin/users/[userId]/route.js +46 -23
- package/dist/routes/api/superadmin/users/route.js +2 -2
- package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
- package/dist/routes/api/user/delete-account/route.js +2 -3
- package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
- package/dist/routes/api/user/plan-flags/route.js +5 -5
- package/dist/routes/api/user/profile/route.js +3 -3
- package/dist/routes/api/v1/auth/signup-with-invite/route.d.ts.map +1 -1
- package/dist/routes/api/v1/auth/signup-with-invite/route.js +80 -44
- package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/post-categories/[id]/route.js +39 -34
- package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
- package/dist/routes/api/v1/post-categories/route.js +18 -14
- package/dist/routes/api/v1/team-invitations/route.d.ts.map +1 -1
- package/dist/routes/api/v1/team-invitations/route.js +12 -5
- package/dist/routes/superadmin/users/page.js +2 -2
- package/dist/templates/next.config.mjs +11 -31
- package/dist/templates/projects/blog/package.json +1 -1
- package/dist/templates/projects/crm/package.json +1 -1
- package/dist/templates/projects/productivity/package.json +1 -1
- package/dist/templates/projects/starter/config/app.config.ts +8 -0
- package/dist/templates/proxy.ts +6 -3
- package/migrations/030_taxonomies_team_writes.sql +29 -0
- package/migrations/031_users_role_suspended.sql +41 -0
- package/package.json +3 -3
- package/scripts/build/registry/__tests__/build-output.test.mjs +1 -1
- package/scripts/build/registry/__tests__/project-mode-root-first.test.mjs +6 -6
- package/scripts/build/registry/__tests__/write-places.test.mjs +1 -1
- package/scripts/build/registry/contracts/__tests__/contracts-wire.test.mjs +1 -1
- package/scripts/build/registry/contracts/__tests__/contracts.test.mjs +1 -1
- package/scripts/build/registry/host/README.md +2 -2
- package/scripts/build/registry/host/__tests__/facade-emitter.test.mjs +14 -13
- package/scripts/build/registry/host/__tests__/host-mode.test.mjs +1 -1
- package/scripts/build/registry/host/__tests__/host-project-composition.test.mjs +1 -1
- package/scripts/build/registry/host/__tests__/host-project.test.mjs +2 -2
- package/scripts/build/registry/host/__tests__/host-proxy-areas.test.mjs +29 -2
- package/scripts/build/registry/host/__tests__/host-robustness.test.mjs +1 -1
- package/scripts/build/registry/host/facade-emitter.mjs +1 -1
- package/scripts/build/registry/host/next-route-exports.json +2 -2
- package/scripts/build/registry/host/proxy-areas.mjs +29 -2
- package/scripts/db/verify-theme-migrations.mjs +1 -1
- package/templates/next.config.mjs +11 -31
- package/templates/projects/blog/package.json +1 -1
- package/templates/projects/crm/package.json +1 -1
- package/templates/projects/productivity/package.json +1 -1
- package/templates/projects/starter/config/app.config.ts +8 -0
- package/templates/proxy.ts +6 -3
- package/tests/jest/__mocks__/@nextsparkjs/registries/permissions-registry.ts +5 -4
|
@@ -2,7 +2,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { Suspense } from "react";
|
|
3
3
|
import { headers } from "next/headers";
|
|
4
4
|
import { redirect } from "next/navigation";
|
|
5
|
-
import {
|
|
5
|
+
import { getAuthorizationRequestSession } from "@nextsparkjs/core/lib/auth/request-session";
|
|
6
6
|
const AREA_ROLES = {
|
|
7
7
|
superadmin: ["superadmin", "developer"],
|
|
8
8
|
devtools: ["developer"]
|
|
@@ -16,7 +16,7 @@ export function loginPathFor(area, pathname) {
|
|
|
16
16
|
return `/login?callbackUrl=${encodeURIComponent(back)}`;
|
|
17
17
|
}
|
|
18
18
|
async function requestSession() {
|
|
19
|
-
return { session: await
|
|
19
|
+
return { session: await getAuthorizationRequestSession(), pathname: (await headers()).get("x-pathname") };
|
|
20
20
|
}
|
|
21
21
|
export async function requireAreaAccess(area) {
|
|
22
22
|
var _a;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
import { getEntityRegistry } from "@nextsparkjs/core/lib/entities/queries";
|
|
4
4
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
@@ -9,7 +9,7 @@ function isEntityConfig(entity) {
|
|
|
9
9
|
export const GET = withRateLimitTier(async (request) => {
|
|
10
10
|
var _a, _b;
|
|
11
11
|
try {
|
|
12
|
-
const session = await
|
|
12
|
+
const session = await getAuthorizationSession(request.headers);
|
|
13
13
|
if (!(session == null ? void 0 : session.user) || session.user.role !== "developer") {
|
|
14
14
|
return NextResponse.json(
|
|
15
15
|
{
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
import { ThemeService } from "@nextsparkjs/core/lib/services/theme.service";
|
|
4
4
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
5
5
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
6
6
|
export const GET = withRateLimitTier(async (request) => {
|
|
7
7
|
try {
|
|
8
|
-
const session = await
|
|
8
|
+
const session = await getAuthorizationSession(request.headers);
|
|
9
9
|
if (!(session == null ? void 0 : session.user) || session.user.role !== "developer") {
|
|
10
10
|
return NextResponse.json(
|
|
11
11
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
import { readFile, stat } from "fs/promises";
|
|
4
4
|
import { join } from "path";
|
|
@@ -7,7 +7,7 @@ import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
|
7
7
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
8
8
|
export const GET = withRateLimitTier(async (request, { params }) => {
|
|
9
9
|
try {
|
|
10
|
-
const session = await
|
|
10
|
+
const session = await getAuthorizationSession(request.headers);
|
|
11
11
|
if (!(session == null ? void 0 : session.user) || session.user.role !== "developer") {
|
|
12
12
|
return NextResponse.json(
|
|
13
13
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
import { readdir, stat } from "fs/promises";
|
|
4
4
|
import { join } from "path";
|
|
@@ -35,7 +35,7 @@ async function buildFileTree(dirPath, basePath) {
|
|
|
35
35
|
}
|
|
36
36
|
export const GET = withRateLimitTier(async (request) => {
|
|
37
37
|
try {
|
|
38
|
-
const session = await
|
|
38
|
+
const session = await getAuthorizationSession(request.headers);
|
|
39
39
|
if (!(session == null ? void 0 : session.user) || session.user.role !== "developer") {
|
|
40
40
|
return NextResponse.json(
|
|
41
41
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
3
|
import { queryWithRLS } from "@nextsparkjs/core/lib/db";
|
|
4
4
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
5
5
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
@@ -7,7 +7,7 @@ import { getBillingGateway } from "@nextsparkjs/core/lib/billing/gateways/factor
|
|
|
7
7
|
export const GET = withRateLimitTier(async (request) => {
|
|
8
8
|
var _a;
|
|
9
9
|
try {
|
|
10
|
-
const session = await
|
|
10
|
+
const session = await getAuthorizationSession(request.headers);
|
|
11
11
|
if (!(session == null ? void 0 : session.user)) {
|
|
12
12
|
return NextResponse.json(
|
|
13
13
|
{ error: "Unauthorized - No session found" },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
3
|
import { queryWithRLS } from "@nextsparkjs/core/lib/db";
|
|
4
4
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
5
5
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
@@ -8,7 +8,7 @@ export const GET = withRateLimitTier(async (request, { params }) => {
|
|
|
8
8
|
var _a;
|
|
9
9
|
try {
|
|
10
10
|
const { teamId } = await params;
|
|
11
|
-
const session = await
|
|
11
|
+
const session = await getAuthorizationSession(request.headers);
|
|
12
12
|
if (!(session == null ? void 0 : session.user)) {
|
|
13
13
|
return NextResponse.json(
|
|
14
14
|
{ error: "Unauthorized - No session found" },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
3
|
import { queryWithRLS } from "@nextsparkjs/core/lib/db";
|
|
4
4
|
import { SYSTEM_ADMIN_TEAM_ID } from "@nextsparkjs/core/lib/api/auth/dual-auth";
|
|
5
5
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
@@ -7,7 +7,7 @@ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
|
7
7
|
export const GET = withRateLimitTier(async (request) => {
|
|
8
8
|
var _a, _b, _c, _d;
|
|
9
9
|
try {
|
|
10
|
-
const session = await
|
|
10
|
+
const session = await getAuthorizationSession(request.headers);
|
|
11
11
|
if (!(session == null ? void 0 : session.user)) {
|
|
12
12
|
return NextResponse.json(
|
|
13
13
|
{ error: "Unauthorized - No session found" },
|
|
@@ -24,10 +24,12 @@ export declare const GET: (request: NextRequest, args_0: RouteParams) => Promise
|
|
|
24
24
|
* Only accessible by superadmin or developer users.
|
|
25
25
|
*
|
|
26
26
|
* Actions:
|
|
27
|
-
* - change-role: Change user's role (requires 'role' field)
|
|
28
|
-
* - suspend: Suspend the user (
|
|
29
|
-
* - unsuspend:
|
|
27
|
+
* - change-role: Change user's role (requires 'role' field: member, or developer when a superadmin asks)
|
|
28
|
+
* - suspend: Suspend the user (role 'suspended'), sign out all their sessions and deactivate their API keys
|
|
29
|
+
* - unsuspend: Give a suspended user back the 'member' role (their API keys stay deactivated)
|
|
30
30
|
* - verify-email: Manually verify user's email
|
|
31
|
+
*
|
|
32
|
+
* Nobody can act on their own account or on a superadmin, so the last superadmin is never suspended.
|
|
31
33
|
*/
|
|
32
34
|
export declare const PATCH: (request: NextRequest, args_0: RouteParams) => Promise<NextResponse>;
|
|
33
35
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/superadmin/users/[userId]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/superadmin/users/[userId]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKxD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AA+BxE,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,GAAG,sEA6KJ,CAAC;AAOb;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,sEAuLN,CAAC;AAEb;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,sEAgIP,CAAC;AAEb,eAAO,MAAM,OAAO,sBAAgB,CAAC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
|
+
import { suspendUser, unsuspendUser } from "@nextsparkjs/core/lib/auth/suspension";
|
|
3
4
|
import { queryWithRLS } from "@nextsparkjs/core/lib/db";
|
|
4
5
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
5
6
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
6
7
|
export const GET = withRateLimitTier(async (request, { params }) => {
|
|
7
8
|
try {
|
|
8
|
-
const session = await
|
|
9
|
+
const session = await getAuthorizationSession(request.headers);
|
|
9
10
|
if (!(session == null ? void 0 : session.user)) {
|
|
10
11
|
return NextResponse.json(
|
|
11
12
|
{ error: "Unauthorized - No session found" },
|
|
@@ -137,7 +138,7 @@ export const GET = withRateLimitTier(async (request, { params }) => {
|
|
|
137
138
|
}, "strict");
|
|
138
139
|
export const PATCH = withRateLimitTier(async (request, { params }) => {
|
|
139
140
|
try {
|
|
140
|
-
const session = await
|
|
141
|
+
const session = await getAuthorizationSession(request.headers);
|
|
141
142
|
if (!(session == null ? void 0 : session.user)) {
|
|
142
143
|
return NextResponse.json(
|
|
143
144
|
{ error: "Unauthorized - No session found" },
|
|
@@ -192,12 +193,24 @@ export const PATCH = withRateLimitTier(async (request, { params }) => {
|
|
|
192
193
|
let updateParams = [];
|
|
193
194
|
switch (action) {
|
|
194
195
|
case "change-role":
|
|
195
|
-
if (!role || !["member", "
|
|
196
|
+
if (!role || !["member", "developer"].includes(role)) {
|
|
196
197
|
return NextResponse.json(
|
|
197
|
-
{ error: "Invalid role. Must be one of: member,
|
|
198
|
+
{ error: "Invalid role. Must be one of: member, developer" },
|
|
198
199
|
{ status: 400 }
|
|
199
200
|
);
|
|
200
201
|
}
|
|
202
|
+
if (targetUser.role === "suspended") {
|
|
203
|
+
return NextResponse.json(
|
|
204
|
+
{ error: "User is suspended. Use the unsuspend action to restore access, then change the role" },
|
|
205
|
+
{ status: 400 }
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
if (role === "developer" && session.user.role !== "superadmin") {
|
|
209
|
+
return NextResponse.json(
|
|
210
|
+
{ error: "Forbidden - Only a superadmin can grant the developer role" },
|
|
211
|
+
{ status: 403 }
|
|
212
|
+
);
|
|
213
|
+
}
|
|
201
214
|
updateQuery = `
|
|
202
215
|
UPDATE "users"
|
|
203
216
|
SET role = $1, "updatedAt" = NOW()
|
|
@@ -206,24 +219,34 @@ export const PATCH = withRateLimitTier(async (request, { params }) => {
|
|
|
206
219
|
`;
|
|
207
220
|
updateParams = [role, userId];
|
|
208
221
|
break;
|
|
209
|
-
case "suspend":
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
222
|
+
case "suspend": {
|
|
223
|
+
const suspended = await suspendUser(userId, session.user.id);
|
|
224
|
+
if (!suspended) {
|
|
225
|
+
return NextResponse.json({ error: "Failed to update user" }, { status: 500 });
|
|
226
|
+
}
|
|
227
|
+
return NextResponse.json({
|
|
228
|
+
success: true,
|
|
229
|
+
action,
|
|
230
|
+
userId,
|
|
231
|
+
message: `User ${action} successful`,
|
|
232
|
+
revoked: suspended,
|
|
233
|
+
metadata: { performedBy: session.user.id, performedAt: (/* @__PURE__ */ new Date()).toISOString(), source: "superadmin-api" }
|
|
234
|
+
});
|
|
235
|
+
}
|
|
218
236
|
case "unsuspend":
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
237
|
+
if (targetUser.role !== "suspended") {
|
|
238
|
+
return NextResponse.json({ error: "User is not suspended" }, { status: 400 });
|
|
239
|
+
}
|
|
240
|
+
if (!await unsuspendUser(userId, session.user.id)) {
|
|
241
|
+
return NextResponse.json({ error: "Failed to update user" }, { status: 500 });
|
|
242
|
+
}
|
|
243
|
+
return NextResponse.json({
|
|
244
|
+
success: true,
|
|
245
|
+
action,
|
|
246
|
+
userId,
|
|
247
|
+
message: `User ${action} successful`,
|
|
248
|
+
metadata: { performedBy: session.user.id, performedAt: (/* @__PURE__ */ new Date()).toISOString(), source: "superadmin-api" }
|
|
249
|
+
});
|
|
227
250
|
case "verify-email":
|
|
228
251
|
updateQuery = `
|
|
229
252
|
UPDATE "users"
|
|
@@ -265,7 +288,7 @@ export const PATCH = withRateLimitTier(async (request, { params }) => {
|
|
|
265
288
|
}, "strict");
|
|
266
289
|
export const DELETE = withRateLimitTier(async (request, { params }) => {
|
|
267
290
|
try {
|
|
268
|
-
const session = await
|
|
291
|
+
const session = await getAuthorizationSession(request.headers);
|
|
269
292
|
if (!(session == null ? void 0 : session.user)) {
|
|
270
293
|
return NextResponse.json(
|
|
271
294
|
{ error: "Unauthorized - No session found" },
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
3
|
import { queryWithRLS } from "@nextsparkjs/core/lib/db";
|
|
4
4
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
5
5
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
6
6
|
export const GET = withRateLimitTier(async (request) => {
|
|
7
7
|
var _a, _b, _c;
|
|
8
8
|
try {
|
|
9
|
-
const session = await
|
|
9
|
+
const session = await getAuthorizationSession(request.headers);
|
|
10
10
|
if (!(session == null ? void 0 : session.user)) {
|
|
11
11
|
return NextResponse.json(
|
|
12
12
|
{ error: "Unauthorized - No session found" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/user/delete-account/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/user/delete-account/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIxD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAGxE,eAAO,MAAM,MAAM,iDAkDP,CAAC;AAEb,eAAO,MAAM,OAAO,sBAAgB,CAAC"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
2
|
import { auth } from "@nextsparkjs/core/lib/auth";
|
|
3
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
4
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
4
5
|
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
5
6
|
import { UserService } from "@nextsparkjs/core/lib/services";
|
|
6
7
|
export const DELETE = withRateLimitTier(async (req) => {
|
|
7
8
|
try {
|
|
8
|
-
const session = await
|
|
9
|
-
headers: req.headers
|
|
10
|
-
});
|
|
9
|
+
const session = await getAuthorizationSession(req.headers);
|
|
11
10
|
if (!(session == null ? void 0 : session.user)) {
|
|
12
11
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
13
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/user/plan-flags/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAavE;;;GAGG;AACH,eAAO,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/user/plan-flags/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAavE;;;GAGG;AACH,eAAO,MAAM,GAAG,iDAyDN,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,KAAK,iDAgFP,CAAC;AAEZ;;;GAGG;AACH,eAAO,MAAM,IAAI,iDA4FL,CAAC;AAEb,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
3
|
import { getUserPlanAndFlags, updateUserPlan, updateUserFlags } from "@nextsparkjs/core/lib/user-data";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
@@ -14,7 +14,7 @@ const planFlagsUpdateSchema = z.object({
|
|
|
14
14
|
});
|
|
15
15
|
export const GET = withRateLimitTier(async (request) => {
|
|
16
16
|
try {
|
|
17
|
-
const session = await
|
|
17
|
+
const session = await getAuthorizationSession(request.headers);
|
|
18
18
|
if (!session) {
|
|
19
19
|
return NextResponse.json(
|
|
20
20
|
{ error: "Authentication required" },
|
|
@@ -23,7 +23,7 @@ export const GET = withRateLimitTier(async (request) => {
|
|
|
23
23
|
}
|
|
24
24
|
const { searchParams } = new URL(request.url);
|
|
25
25
|
const validation = planFlagsQuerySchema.safeParse({
|
|
26
|
-
userId: searchParams.get("userId")
|
|
26
|
+
userId: searchParams.get("userId") ?? void 0
|
|
27
27
|
});
|
|
28
28
|
if (!validation.success) {
|
|
29
29
|
return NextResponse.json(
|
|
@@ -60,7 +60,7 @@ export const GET = withRateLimitTier(async (request) => {
|
|
|
60
60
|
}, "read");
|
|
61
61
|
export const PATCH = withRateLimitTier(async (request) => {
|
|
62
62
|
try {
|
|
63
|
-
const session = await
|
|
63
|
+
const session = await getAuthorizationSession(request.headers);
|
|
64
64
|
if (!session) {
|
|
65
65
|
return NextResponse.json(
|
|
66
66
|
{ error: "Authentication required" },
|
|
@@ -125,7 +125,7 @@ export const PATCH = withRateLimitTier(async (request) => {
|
|
|
125
125
|
}, "write");
|
|
126
126
|
export const POST = withRateLimitTier(async (request) => {
|
|
127
127
|
try {
|
|
128
|
-
const session = await
|
|
128
|
+
const session = await getAuthorizationSession(request.headers);
|
|
129
129
|
if (!session) {
|
|
130
130
|
return NextResponse.json(
|
|
131
131
|
{ error: "Authentication required" },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { getAuthorizationSession } from "@nextsparkjs/core/lib/auth/authorization-session";
|
|
3
3
|
import { queryOneWithRLS, mutateWithRLS, queryOne } from "@nextsparkjs/core/lib/db";
|
|
4
4
|
import { profileSchema } from "@nextsparkjs/core/lib/validation";
|
|
5
5
|
import { MetaService, MetaValueTooLargeError } from "@nextsparkjs/core/lib/services/meta.service";
|
|
@@ -10,7 +10,7 @@ export const GET = withRateLimitTier(async (request) => {
|
|
|
10
10
|
const includeMeta = url.searchParams.get("includeMeta") === "true";
|
|
11
11
|
try {
|
|
12
12
|
const sessionHeaders = request.headers;
|
|
13
|
-
const session = await
|
|
13
|
+
const session = await getAuthorizationSession(sessionHeaders);
|
|
14
14
|
if (!(session == null ? void 0 : session.user)) {
|
|
15
15
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
16
16
|
}
|
|
@@ -44,7 +44,7 @@ export const GET = withRateLimitTier(async (request) => {
|
|
|
44
44
|
export const PATCH = withRateLimitTier(async (request) => {
|
|
45
45
|
try {
|
|
46
46
|
const sessionHeaders = request.headers;
|
|
47
|
-
const session = await
|
|
47
|
+
const session = await getAuthorizationSession(sessionHeaders);
|
|
48
48
|
if (!(session == null ? void 0 : session.user)) {
|
|
49
49
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
50
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/auth/signup-with-invite/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAkBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/auth/signup-with-invite/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAkBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAYD,eAAO,MAAM,IAAI,iDAsQP,CAAA"}
|
|
@@ -19,20 +19,12 @@ export const POST = withRateLimitTier(withApiLogging(
|
|
|
19
19
|
async (req) => {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
try {
|
|
22
|
-
|
|
23
|
-
const response = createApiError(
|
|
24
|
-
"Password authentication is unavailable",
|
|
25
|
-
503,
|
|
26
|
-
null,
|
|
27
|
-
"AUTH_METHOD_UNAVAILABLE"
|
|
28
|
-
);
|
|
29
|
-
return addCorsHeaders(response, req);
|
|
30
|
-
}
|
|
22
|
+
const passwordLogin = isPasswordLoginEnabled(AUTH_CONFIG);
|
|
31
23
|
const body = await req.json();
|
|
32
24
|
const { email, password, firstName, lastName, inviteToken } = body;
|
|
33
|
-
if (!email || !password || !inviteToken) {
|
|
25
|
+
if (!email || passwordLogin && !password || !inviteToken) {
|
|
34
26
|
const response = createApiError(
|
|
35
|
-
"Email, password, and invitation token are required",
|
|
27
|
+
passwordLogin ? "Email, password, and invitation token are required" : "Email and invitation token are required",
|
|
36
28
|
400,
|
|
37
29
|
null,
|
|
38
30
|
"MISSING_FIELDS"
|
|
@@ -44,7 +36,7 @@ export const POST = withRateLimitTier(withApiLogging(
|
|
|
44
36
|
const response = createApiError("Invalid email format", 400, null, "INVALID_EMAIL");
|
|
45
37
|
return addCorsHeaders(response, req);
|
|
46
38
|
}
|
|
47
|
-
if (password.length < 8) {
|
|
39
|
+
if (passwordLogin && password.length < 8) {
|
|
48
40
|
const response = createApiError(
|
|
49
41
|
"Password must be at least 8 characters",
|
|
50
42
|
400,
|
|
@@ -86,45 +78,89 @@ export const POST = withRateLimitTier(withApiLogging(
|
|
|
86
78
|
const response = createApiError("Invitation has expired", 410, null, "INVITATION_EXPIRED");
|
|
87
79
|
return addCorsHeaders(response, req);
|
|
88
80
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
81
|
+
let userId;
|
|
82
|
+
const signupContext = { skipTeamCreation: true, invitedTeamId: invitation.teamId };
|
|
83
|
+
const name = firstName && lastName ? `${firstName} ${lastName}` : firstName || "";
|
|
84
|
+
if (passwordLogin) {
|
|
85
|
+
const signUpRequest = new Request(`${process.env.NEXT_PUBLIC_APP_URL}${withBasePath("/api/auth/sign-up/email")}`, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "application/json"
|
|
89
|
+
},
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
email,
|
|
92
|
+
password,
|
|
93
|
+
name,
|
|
94
|
+
firstName,
|
|
95
|
+
lastName,
|
|
96
|
+
language: I18N_CONFIG.defaultLocale
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
const signUpResponse = await withSignupContext(signupContext, () => auth.handler(signUpRequest));
|
|
100
|
+
if (!signUpResponse.ok) {
|
|
101
|
+
const errorData = await signUpResponse.json();
|
|
102
|
+
if (((_a = errorData.message) == null ? void 0 : _a.includes("already exists")) || errorData.code === "USER_ALREADY_EXISTS") {
|
|
103
|
+
const response2 = createApiError(
|
|
104
|
+
"An account with this email already exists. Please sign in instead.",
|
|
105
|
+
409,
|
|
106
|
+
null,
|
|
107
|
+
"USER_ALREADY_EXISTS"
|
|
108
|
+
);
|
|
109
|
+
return addCorsHeaders(response2, req);
|
|
110
|
+
}
|
|
111
|
+
const response = createApiError(
|
|
112
|
+
errorData.message || "Failed to create account",
|
|
113
|
+
signUpResponse.status,
|
|
114
|
+
null,
|
|
115
|
+
"SIGNUP_FAILED"
|
|
116
|
+
);
|
|
117
|
+
return addCorsHeaders(response, req);
|
|
118
|
+
}
|
|
119
|
+
const signUpData = await signUpResponse.json();
|
|
120
|
+
userId = (_b = signUpData.user) == null ? void 0 : _b.id;
|
|
121
|
+
} else {
|
|
122
|
+
const { internalAdapter } = await auth.$context;
|
|
123
|
+
if (await internalAdapter.findUserByEmail(email.toLowerCase())) {
|
|
124
|
+
const response = createApiError(
|
|
111
125
|
"An account with this email already exists. Please sign in instead.",
|
|
112
126
|
409,
|
|
113
127
|
null,
|
|
114
128
|
"USER_ALREADY_EXISTS"
|
|
115
129
|
);
|
|
116
|
-
return addCorsHeaders(
|
|
130
|
+
return addCorsHeaders(response, req);
|
|
117
131
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
let user;
|
|
133
|
+
try {
|
|
134
|
+
user = await withSignupContext(signupContext, () => internalAdapter.createUser({
|
|
135
|
+
email: email.toLowerCase(),
|
|
136
|
+
emailVerified: true,
|
|
137
|
+
name,
|
|
138
|
+
firstName,
|
|
139
|
+
lastName,
|
|
140
|
+
language: I18N_CONFIG.defaultLocale
|
|
141
|
+
}));
|
|
142
|
+
} catch (error) {
|
|
143
|
+
const message = error instanceof Error ? error.message : "";
|
|
144
|
+
const refused = /^(DOMAIN_NOT_ALLOWED|SIGNUP_RESTRICTED): (.*)$/s.exec(message);
|
|
145
|
+
if (refused) {
|
|
146
|
+
return addCorsHeaders(createApiError(refused[2], 403, null, refused[1]), req);
|
|
147
|
+
}
|
|
148
|
+
if (error.code === "23505" || /duplicate key/i.test(message)) {
|
|
149
|
+
const response = createApiError(
|
|
150
|
+
"An account with this email already exists. Please sign in instead.",
|
|
151
|
+
409,
|
|
152
|
+
null,
|
|
153
|
+
"USER_ALREADY_EXISTS"
|
|
154
|
+
);
|
|
155
|
+
return addCorsHeaders(response, req);
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
if (!user) {
|
|
160
|
+
return addCorsHeaders(createApiError("Account creation was refused", 403, null, "SIGNUP_FAILED"), req);
|
|
161
|
+
}
|
|
162
|
+
userId = user.id;
|
|
125
163
|
}
|
|
126
|
-
const signUpData = await signUpResponse.json();
|
|
127
|
-
const userId = (_b = signUpData.user) == null ? void 0 : _b.id;
|
|
128
164
|
if (!userId) {
|
|
129
165
|
const response = createApiError(
|
|
130
166
|
"Failed to create account - no user ID returned",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/post-categories/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/post-categories/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAiCvE,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BA2BrC,CAAC;AAIX,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BA+HpC,CAAC;AAIZ,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAuDpC,CAAC;AAEZ,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
|