@carlonicora/nextjs-jsonapi 1.30.0 → 1.31.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.
Files changed (49) hide show
  1. package/dist/{BlockNoteEditor-CEJE3YHQ.mjs → BlockNoteEditor-N5ODXWD2.mjs} +3 -3
  2. package/dist/{BlockNoteEditor-TUJ3VCS3.js → BlockNoteEditor-PJOOJ3LX.js} +13 -13
  3. package/dist/{BlockNoteEditor-TUJ3VCS3.js.map → BlockNoteEditor-PJOOJ3LX.js.map} +1 -1
  4. package/dist/billing/index.js +331 -331
  5. package/dist/billing/index.mjs +2 -2
  6. package/dist/{chunk-BHKXZF2I.js → chunk-6GVSJFRG.js} +528 -444
  7. package/dist/chunk-6GVSJFRG.js.map +1 -0
  8. package/dist/{chunk-XY6HEWHI.mjs → chunk-CQCHSJLC.mjs} +977 -893
  9. package/dist/chunk-CQCHSJLC.mjs.map +1 -0
  10. package/dist/{chunk-5KQXRLK3.js → chunk-KYG2PIRB.js} +16 -1
  11. package/dist/chunk-KYG2PIRB.js.map +1 -0
  12. package/dist/{chunk-WQ3KF6BG.mjs → chunk-YCP2OMFD.mjs} +16 -1
  13. package/dist/{chunk-WQ3KF6BG.mjs.map → chunk-YCP2OMFD.mjs.map} +1 -1
  14. package/dist/client/index.js +3 -3
  15. package/dist/client/index.mjs +2 -2
  16. package/dist/components/index.d.mts +17 -1
  17. package/dist/components/index.d.ts +17 -1
  18. package/dist/components/index.js +7 -3
  19. package/dist/components/index.js.map +1 -1
  20. package/dist/components/index.mjs +6 -2
  21. package/dist/contexts/index.js +3 -3
  22. package/dist/contexts/index.mjs +2 -2
  23. package/dist/core/index.d.mts +2 -2
  24. package/dist/core/index.d.ts +2 -2
  25. package/dist/core/index.js +2 -2
  26. package/dist/core/index.mjs +1 -1
  27. package/dist/index.d.mts +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +2 -2
  30. package/dist/index.mjs +1 -1
  31. package/dist/{s3.service-DsXo9nop.d.ts → s3.service-CoC0k0iu.d.ts} +11 -0
  32. package/dist/{s3.service-BMT7W6KS.d.mts → s3.service-Duh9HW2n.d.mts} +11 -0
  33. package/dist/server/index.d.mts +1 -1
  34. package/dist/server/index.d.ts +1 -1
  35. package/dist/server/index.js +3 -3
  36. package/dist/server/index.mjs +1 -1
  37. package/package.json +1 -1
  38. package/src/components/forms/GdprConsentCheckbox.tsx +45 -0
  39. package/src/components/forms/index.ts +1 -0
  40. package/src/features/auth/components/GdprConsentSection.tsx +50 -0
  41. package/src/features/auth/components/forms/Register.tsx +11 -0
  42. package/src/features/auth/components/index.ts +1 -0
  43. package/src/features/auth/data/auth.interface.ts +3 -0
  44. package/src/features/auth/data/auth.service.ts +21 -0
  45. package/src/features/auth/data/auth.ts +3 -0
  46. package/dist/chunk-5KQXRLK3.js.map +0 -1
  47. package/dist/chunk-BHKXZF2I.js.map +0 -1
  48. package/dist/chunk-XY6HEWHI.mjs.map +0 -1
  49. /package/dist/{BlockNoteEditor-CEJE3YHQ.mjs.map → BlockNoteEditor-N5ODXWD2.mjs.map} +0 -0
@@ -231,6 +231,9 @@ type AuthInput = {
231
231
  companyName?: string;
232
232
  partitaIva?: string;
233
233
  codiceFiscale?: string;
234
+ termsAcceptedAt?: string;
235
+ marketingConsent?: boolean;
236
+ marketingConsentAt?: string | null;
234
237
  };
235
238
  type AuthQuery = {
236
239
  userId?: string;
@@ -283,6 +286,14 @@ declare class AuthService extends AbstractService {
283
286
  static saveToken(params: {
284
287
  dehydratedAuth: JsonApiHydratedDataInterface;
285
288
  }): Promise<void>;
289
+ static completeOAuthRegistration(params: {
290
+ pendingId: string;
291
+ termsAcceptedAt: string;
292
+ marketingConsent: boolean;
293
+ marketingConsentAt: string | null;
294
+ }): Promise<{
295
+ code: string;
296
+ }>;
286
297
  }
287
298
 
288
299
  declare class CompanyService extends AbstractService {
@@ -231,6 +231,9 @@ type AuthInput = {
231
231
  companyName?: string;
232
232
  partitaIva?: string;
233
233
  codiceFiscale?: string;
234
+ termsAcceptedAt?: string;
235
+ marketingConsent?: boolean;
236
+ marketingConsentAt?: string | null;
234
237
  };
235
238
  type AuthQuery = {
236
239
  userId?: string;
@@ -283,6 +286,14 @@ declare class AuthService extends AbstractService {
283
286
  static saveToken(params: {
284
287
  dehydratedAuth: JsonApiHydratedDataInterface;
285
288
  }): Promise<void>;
289
+ static completeOAuthRegistration(params: {
290
+ pendingId: string;
291
+ termsAcceptedAt: string;
292
+ marketingConsent: boolean;
293
+ marketingConsentAt: string | null;
294
+ }): Promise<{
295
+ code: string;
296
+ }>;
286
297
  }
287
298
 
288
299
  declare class CompanyService extends AbstractService {
@@ -2,7 +2,7 @@ import { A as ApiData } from '../ApiData-DPKNfY-9.mjs';
2
2
  import { M as ModuleWithPermissions, A as Action } from '../notification.interface-D5MbtfZK.mjs';
3
3
  import { A as ApiRequestDataTypeInterface } from '../ApiRequestDataTypeInterface-CUKFDBx2.mjs';
4
4
  import { A as ApiResponseInterface } from '../ApiResponseInterface-zeewugD7.mjs';
5
- export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-BMT7W6KS.mjs';
5
+ export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-Duh9HW2n.mjs';
6
6
  import 'lucide-react';
7
7
  import '../ApiDataInterface-DPP8s46n.mjs';
8
8
  import '../content.interface-BSpowEiW.mjs';
@@ -2,7 +2,7 @@ import { A as ApiData } from '../ApiData-DPKNfY-9.js';
2
2
  import { M as ModuleWithPermissions, A as Action } from '../notification.interface-CmKmObIU.js';
3
3
  import { A as ApiRequestDataTypeInterface } from '../ApiRequestDataTypeInterface-CUKFDBx2.js';
4
4
  import { A as ApiResponseInterface } from '../ApiResponseInterface-CAIAeP5d.js';
5
- export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-DsXo9nop.js';
5
+ export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-CoC0k0iu.js';
6
6
  import 'lucide-react';
7
7
  import '../ApiDataInterface-DPP8s46n.js';
8
8
  import '../content.interface-DFQ7mkpL.js';
@@ -15,7 +15,7 @@ var _chunk3ZPK4QOBjs = require('../chunk-3ZPK4QOB.js');
15
15
 
16
16
 
17
17
 
18
- var _chunk5KQXRLK3js = require('../chunk-5KQXRLK3.js');
18
+ var _chunkKYG2PIRBjs = require('../chunk-KYG2PIRB.js');
19
19
  require('../chunk-LXKSUWAV.js');
20
20
  require('../chunk-IBS6NI7D.js');
21
21
 
@@ -86,7 +86,7 @@ var ServerSession = class {
86
86
  if (!rawModules) return false;
87
87
  const modules = JSON.parse(_pako2.default.ungzip(Buffer.from(rawModules, "base64"), { to: "string" }));
88
88
  const selectedModule = modules.find((module) => module.id === params.module.moduleId);
89
- return _chunk5KQXRLK3js.checkPermissionsFromServer.call(void 0, {
89
+ return _chunkKYG2PIRBjs.checkPermissionsFromServer.call(void 0, {
90
90
  module: params.module,
91
91
  action: params.action,
92
92
  data: params.data,
@@ -296,5 +296,5 @@ _chunk7QVYU63Ejs.__name.call(void 0, ServerJsonApiDelete, "ServerJsonApiDelete")
296
296
 
297
297
 
298
298
 
299
- exports.ServerAuthService = _chunk5KQXRLK3js.AuthService; exports.ServerCompanyService = _chunk5KQXRLK3js.CompanyService; exports.ServerContentService = _chunk5KQXRLK3js.ContentService; exports.ServerFeatureService = _chunk5KQXRLK3js.FeatureService; exports.ServerJsonApiDelete = ServerJsonApiDelete; exports.ServerJsonApiGet = ServerJsonApiGet; exports.ServerJsonApiPatch = ServerJsonApiPatch; exports.ServerJsonApiPost = ServerJsonApiPost; exports.ServerJsonApiPut = ServerJsonApiPut; exports.ServerNotificationService = _chunk5KQXRLK3js.NotificationService; exports.ServerPushService = _chunk5KQXRLK3js.PushService; exports.ServerRoleService = _chunk5KQXRLK3js.RoleService; exports.ServerS3Service = _chunk5KQXRLK3js.S3Service; exports.ServerSession = ServerSession; exports.ServerUserService = _chunk5KQXRLK3js.UserService; exports.configureServerJsonApi = configureServerJsonApi; exports.getServerApiUrl = getServerApiUrl; exports.getServerAppUrl = getServerAppUrl; exports.getServerToken = _chunkYUO55Q5Ajs.getServerToken; exports.getServerTrackablePages = getServerTrackablePages; exports.invalidateCacheTag = invalidateCacheTag; exports.invalidateCacheTags = invalidateCacheTags; exports.serverRequest = _chunk3ZPK4QOBjs.serverRequest;
299
+ exports.ServerAuthService = _chunkKYG2PIRBjs.AuthService; exports.ServerCompanyService = _chunkKYG2PIRBjs.CompanyService; exports.ServerContentService = _chunkKYG2PIRBjs.ContentService; exports.ServerFeatureService = _chunkKYG2PIRBjs.FeatureService; exports.ServerJsonApiDelete = ServerJsonApiDelete; exports.ServerJsonApiGet = ServerJsonApiGet; exports.ServerJsonApiPatch = ServerJsonApiPatch; exports.ServerJsonApiPost = ServerJsonApiPost; exports.ServerJsonApiPut = ServerJsonApiPut; exports.ServerNotificationService = _chunkKYG2PIRBjs.NotificationService; exports.ServerPushService = _chunkKYG2PIRBjs.PushService; exports.ServerRoleService = _chunkKYG2PIRBjs.RoleService; exports.ServerS3Service = _chunkKYG2PIRBjs.S3Service; exports.ServerSession = ServerSession; exports.ServerUserService = _chunkKYG2PIRBjs.UserService; exports.configureServerJsonApi = configureServerJsonApi; exports.getServerApiUrl = getServerApiUrl; exports.getServerAppUrl = getServerAppUrl; exports.getServerToken = _chunkYUO55Q5Ajs.getServerToken; exports.getServerTrackablePages = getServerTrackablePages; exports.invalidateCacheTag = invalidateCacheTag; exports.invalidateCacheTags = invalidateCacheTags; exports.serverRequest = _chunk3ZPK4QOBjs.serverRequest;
300
300
  //# sourceMappingURL=index.js.map
@@ -15,7 +15,7 @@ import {
15
15
  S3Service,
16
16
  UserService,
17
17
  checkPermissionsFromServer
18
- } from "../chunk-WQ3KF6BG.mjs";
18
+ } from "../chunk-YCP2OMFD.mjs";
19
19
  import "../chunk-AUXK7QSA.mjs";
20
20
  import "../chunk-C7C7VY4F.mjs";
21
21
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carlonicora/nextjs-jsonapi",
3
- "version": "1.30.0",
3
+ "version": "1.31.1",
4
4
  "description": "Next.js JSON:API client with server/client support and caching",
5
5
  "author": "Carlo Nicora",
6
6
  "license": "GPL-3.0-or-later",
@@ -0,0 +1,45 @@
1
+ "use client";
2
+
3
+ import { ReactNode } from "react";
4
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
5
+ import { Checkbox, FieldDescription } from "../../shadcnui";
6
+ import { FormFieldWrapper } from "./FormFieldWrapper";
7
+
8
+ interface GdprConsentCheckboxProps<T extends FieldValues> {
9
+ form: UseFormReturn<T>;
10
+ id: Path<T>;
11
+ label: ReactNode;
12
+ description?: string;
13
+ required?: boolean;
14
+ }
15
+
16
+ export function GdprConsentCheckbox<T extends FieldValues>({
17
+ form,
18
+ id,
19
+ label,
20
+ description,
21
+ required,
22
+ }: GdprConsentCheckboxProps<T>) {
23
+ return (
24
+ <FormFieldWrapper form={form} name={id} orientation="horizontal">
25
+ {(field) => (
26
+ <div className="flex flex-row items-start space-x-3 space-y-0">
27
+ <Checkbox
28
+ checked={field.value}
29
+ onCheckedChange={field.onChange}
30
+ aria-required={required}
31
+ />
32
+ <div className="space-y-1 leading-none">
33
+ <span className="text-sm font-normal">
34
+ {label}
35
+ {required && <span className="text-destructive ml-1">*</span>}
36
+ </span>
37
+ {description && (
38
+ <FieldDescription className="text-xs">{description}</FieldDescription>
39
+ )}
40
+ </div>
41
+ </div>
42
+ )}
43
+ </FormFieldWrapper>
44
+ );
45
+ }
@@ -17,6 +17,7 @@ export * from "./FormSelect";
17
17
  export * from "./FormSlider";
18
18
  export * from "./FormSwitch";
19
19
  export * from "./FormTextarea";
20
+ export * from "./GdprConsentCheckbox";
20
21
  export * from "./MultiFileUploader";
21
22
  export * from "./PasswordInput";
22
23
  export { FormFeatures } from "../../features/feature/components/forms/FormFeatures";
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import { useTranslations } from "next-intl";
4
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
5
+ import { GdprConsentCheckbox } from "../../../components/forms/GdprConsentCheckbox";
6
+ import { Link } from "../../../shadcnui";
7
+
8
+ interface GdprConsentSectionProps<T extends FieldValues> {
9
+ form: UseFormReturn<T>;
10
+ termsCheckboxId?: Path<T>;
11
+ marketingCheckboxId?: Path<T>;
12
+ }
13
+
14
+ export function GdprConsentSection<T extends FieldValues>({
15
+ form,
16
+ termsCheckboxId = "termsAccepted" as Path<T>,
17
+ marketingCheckboxId = "marketingConsent" as Path<T>,
18
+ }: GdprConsentSectionProps<T>) {
19
+ const t = useTranslations("auth.gdpr");
20
+
21
+ const termsLabel = (
22
+ <>
23
+ {t("terms_prefix")}{" "}
24
+ <Link href="/terms" target="_blank" rel="noopener" className="underline">
25
+ {t("terms_of_service")}
26
+ </Link>{" "}
27
+ {t("and")}{" "}
28
+ <Link href="/privacy" target="_blank" rel="noopener" className="underline">
29
+ {t("privacy_policy")}
30
+ </Link>
31
+ </>
32
+ );
33
+
34
+ return (
35
+ <div className="space-y-4 py-4">
36
+ <GdprConsentCheckbox
37
+ form={form}
38
+ id={termsCheckboxId}
39
+ label={termsLabel}
40
+ required
41
+ />
42
+ <GdprConsentCheckbox
43
+ form={form}
44
+ id={marketingCheckboxId}
45
+ label={t("marketing_consent")}
46
+ description={t("marketing_description")}
47
+ />
48
+ </div>
49
+ );
50
+ }
@@ -8,6 +8,7 @@ import { SubmitHandler, useForm } from "react-hook-form";
8
8
  import { v4 } from "uuid";
9
9
  import { z } from "zod";
10
10
  import { errorToast, FormInput, FormPassword } from "../../../../components";
11
+ import { GdprConsentSection } from "../GdprConsentSection";
11
12
  import {
12
13
  Button,
13
14
  CardContent,
@@ -44,6 +45,10 @@ export default function Register() {
44
45
  .regex(/^(?=.*[0-9])(?=.*[^a-zA-Z0-9]).*$/, {
45
46
  message: t(`auth.errors.password_invalid_format`),
46
47
  }),
48
+ termsAccepted: z.literal(true, {
49
+ message: t("auth.gdpr.terms_required"),
50
+ }),
51
+ marketingConsent: z.boolean().optional(),
47
52
  });
48
53
 
49
54
  const form = useForm<z.infer<typeof formSchema>>({
@@ -53,6 +58,8 @@ export default function Register() {
53
58
  name: "",
54
59
  email: "",
55
60
  password: "",
61
+ termsAccepted: false as unknown as true,
62
+ marketingConsent: false,
56
63
  },
57
64
  });
58
65
 
@@ -64,6 +71,9 @@ export default function Register() {
64
71
  name: values.name,
65
72
  email: values.email,
66
73
  password: values.password,
74
+ termsAcceptedAt: new Date().toISOString(),
75
+ marketingConsent: values.marketingConsent ?? false,
76
+ marketingConsentAt: values.marketingConsent ? new Date().toISOString() : null,
67
77
  };
68
78
 
69
79
  await AuthService.register(payload);
@@ -120,6 +130,7 @@ export default function Register() {
120
130
  name={t(`user.fields.password.label`)}
121
131
  placeholder={t(`user.fields.password.placeholder`)}
122
132
  />
133
+ <GdprConsentSection form={form} />
123
134
  <Button className="mt-4 w-full" type={"submit"}>
124
135
  {t(`auth.buttons.register`)}
125
136
  </Button>
@@ -1,3 +1,4 @@
1
1
  export * from "./containers";
2
2
  export * from "./details";
3
3
  export * from "./forms";
4
+ export * from "./GdprConsentSection";
@@ -9,6 +9,9 @@ export type AuthInput = {
9
9
  companyName?: string;
10
10
  partitaIva?: string;
11
11
  codiceFiscale?: string;
12
+ termsAcceptedAt?: string;
13
+ marketingConsent?: boolean;
14
+ marketingConsentAt?: string | null;
12
15
  };
13
16
 
14
17
  export type AuthQuery = {
@@ -154,4 +154,25 @@ export class AuthService extends AbstractService {
154
154
  });
155
155
  }
156
156
  }
157
+
158
+ static async completeOAuthRegistration(params: {
159
+ pendingId: string;
160
+ termsAcceptedAt: string;
161
+ marketingConsent: boolean;
162
+ marketingConsentAt: string | null;
163
+ }): Promise<{ code: string }> {
164
+ const endpoint = new EndpointCreator({ endpoint: Modules.Auth, id: "oauth", childEndpoint: "complete" });
165
+
166
+ const response: ApiResponseInterface = await JsonApiPost({
167
+ classKey: Modules.Auth,
168
+ endpoint: endpoint.generate(),
169
+ body: params,
170
+ overridesJsonApiCreation: true,
171
+ language: "en",
172
+ });
173
+
174
+ if (!response.ok) throw new Error(response.error);
175
+
176
+ return response.data as unknown as { code: string };
177
+ }
157
178
  }
@@ -46,6 +46,9 @@ export class Auth extends AbstractApiData implements AuthInterface {
46
46
  if (data.name !== undefined) response.data.attributes.name = data.name;
47
47
  if (data.companyName !== undefined) response.data.attributes.companyName = data.companyName;
48
48
  if (data.password !== undefined) response.data.attributes.password = data.password;
49
+ if (data.termsAcceptedAt !== undefined) response.data.attributes.termsAcceptedAt = data.termsAcceptedAt;
50
+ if (data.marketingConsent !== undefined) response.data.attributes.marketingConsent = data.marketingConsent;
51
+ if (data.marketingConsentAt !== undefined) response.data.attributes.marketingConsentAt = data.marketingConsentAt;
49
52
 
50
53
  return response;
51
54
  }