diff --git a/apps/web/src/components/ui/LazyComponent.tsx b/apps/web/src/components/ui/LazyComponent.tsx index 8cb979c17..15ac64581 100644 --- a/apps/web/src/components/ui/LazyComponent.tsx +++ b/apps/web/src/components/ui/LazyComponent.tsx @@ -51,5 +51,6 @@ export { LazyEducation, LazySupport, LazyLanding, + LazyDmca, } from './lazy-component'; export type { LazyComponentProps, LazyErrorFallbackProps, LazyErrorBoundaryProps } from './lazy-component'; diff --git a/apps/web/src/components/ui/lazy-component/index.ts b/apps/web/src/components/ui/lazy-component/index.ts index 80d8cbc1c..17b343ae1 100644 --- a/apps/web/src/components/ui/lazy-component/index.ts +++ b/apps/web/src/components/ui/lazy-component/index.ts @@ -54,4 +54,5 @@ export { LazyEducation, LazySupport, LazyLanding, + LazyDmca, } from './lazyExports'; diff --git a/apps/web/src/components/ui/lazy-component/lazyExports.ts b/apps/web/src/components/ui/lazy-component/lazyExports.ts index 708aaad25..a6dabd607 100644 --- a/apps/web/src/components/ui/lazy-component/lazyExports.ts +++ b/apps/web/src/components/ui/lazy-component/lazyExports.ts @@ -357,3 +357,9 @@ export const LazyLanding = createLazyComponent( undefined, 'Landing', ); +// Legal — DMCA notice & designated agent +export const LazyDmca = createLazyComponent( + () => import('@/features/legal/pages/DmcaPage'), + undefined, + 'Dmca', +); diff --git a/apps/web/src/features/legal/pages/DmcaPage.tsx b/apps/web/src/features/legal/pages/DmcaPage.tsx new file mode 100644 index 000000000..3f747b279 --- /dev/null +++ b/apps/web/src/features/legal/pages/DmcaPage.tsx @@ -0,0 +1,270 @@ +import { useEffect } from 'react'; +import { Link } from 'react-router-dom'; + +const DMCA_AGENT = { + designationNumber: 'PENDING — registration in progress', + organizationName: 'Veza', + agentName: 'Veza DMCA Designated Agent', + email: 'dmca@veza.fr', + phone: '+33 — pending', + postalAddress: 'Veza — DMCA Agent, France (full postal address pending)', + websiteUrl: 'https://veza.fr', +} as const; + +export default function DmcaPage() { + useEffect(() => { + document.title = 'DMCA Notice & Designated Agent — Veza'; + }, []); + + return ( +
+
+
+ + ← Veza + +

+ DMCA Copyright Policy & Designated Agent +

+

+ Veza respects the intellectual property rights of others and expects users to do the + same. This page describes how to submit a notice of alleged copyright infringement + under the U.S. Digital Millennium Copyright Act (17 U.S.C. § 512), and identifies the + designated agent appointed to receive such notices. +

+

+ Veza respecte les droits de propriété intellectuelle. Cette page décrit la procédure + de notification d'atteinte au droit d'auteur (DMCA / 17 U.S.C. § 512) et + désigne l'agent compétent pour recevoir ces notifications. +

+
+ +
+

+ Designated Agent — U.S. Copyright Office +

+
+
+
Organization
+
+ {DMCA_AGENT.organizationName} +
+ +
Designated Agent
+
+ {DMCA_AGENT.agentName} +
+ +
Email
+
+ + {DMCA_AGENT.email} + +
+ +
Phone
+
+ {DMCA_AGENT.phone} +
+ +
Postal address
+
+ {DMCA_AGENT.postalAddress} +
+ +
Designation Number
+
+ {DMCA_AGENT.designationNumber} +
+ +
Public directory
+
+ + dmca.copyright.gov/osp + +
+
+
+

+ Veza is in the process of completing its registration with the U.S. Copyright Office + DMCA Designated Agent Directory. The designation number above will be updated upon + confirmation. Notices may already be sent to the email address listed. +

+
+ +
+

+ How to file a DMCA notice +

+

+ To be effective under 17 U.S.C. § 512(c)(3), a written notification of claimed + infringement must include all of the following elements. Send it by email to{' '} + + {DMCA_AGENT.email} + {' '} + with subject line DMCA Notice. +

+
    +
  1. + A physical or electronic signature of the person authorized to act on behalf of the + owner of the exclusive right that is allegedly infringed. +
  2. +
  3. + Identification of the copyrighted work claimed to have been infringed (or, for + multiple works, a representative list). +
  4. +
  5. + Identification of the material claimed to be infringing — including the URL on Veza + (e.g.{' '} + https://veza.fr/tracks/<id> + ) — and information reasonably sufficient to allow Veza to locate it. +
  6. +
  7. + Information reasonably sufficient to permit Veza to contact the complaining party: + full name, postal address, telephone number, and email address. +
  8. +
  9. + A statement that the complaining party has a good-faith belief that use of the + material in the manner complained of is not authorized by the copyright owner, its + agent, or the law. +
  10. +
  11. + A statement, made under penalty of perjury, that the information in the notification + is accurate, and that the complaining party is authorized to act on behalf of the + owner of an exclusive right that is allegedly infringed. +
  12. +
+

+ Upon receipt of a complete and valid notice, Veza will expeditiously remove or disable + access to the identified material, notify the user who posted it, and document the + action in its internal audit log. +

+
+ +
+

+ Counter-notification +

+

+ A user whose content has been removed in response to a DMCA notice may submit a + counter-notification under 17 U.S.C. § 512(g). The counter-notification must include + the user's identification, the location of the removed material, a statement + under penalty of perjury that the user has a good-faith belief that the material was + removed in error, and the user's consent to jurisdiction. Send counter-notices to + the same email address as DMCA notices. +

+
+ +
+

+ Repeat-infringer policy +

+

+ In accordance with 17 U.S.C. § 512(i), Veza maintains a policy providing for the + termination, in appropriate circumstances, of accounts of users who are repeat + infringers. Strikes are tracked internally and may result in account suspension or + permanent termination at Veza's discretion. +

+
+ +
+

+ Misrepresentation +

+

+ Under 17 U.S.C. § 512(f), any person who knowingly materially misrepresents that + material is infringing — or that material was removed by mistake or misidentification + — may be liable for damages, including costs and attorneys' fees, incurred by the + alleged infringer, by any copyright owner or its licensee, or by Veza. +

+
+ + +
+
+ ); +} diff --git a/apps/web/src/router/index.test.tsx b/apps/web/src/router/index.test.tsx index 6daa20dc2..3181f83b3 100644 --- a/apps/web/src/router/index.test.tsx +++ b/apps/web/src/router/index.test.tsx @@ -95,6 +95,7 @@ vi.mock('@/components/ui/LazyComponent', () => ({ LazyEducation: () =>
Education Page
, LazySupport: () =>
Support Page
, LazyLanding: () =>
Landing Page
, + LazyDmca: () =>
DMCA Page
, })); // Mock DashboardLayout (used by ProtectedLayoutRoute) diff --git a/apps/web/src/router/routeConfig.tsx b/apps/web/src/router/routeConfig.tsx index 61405eb7b..51d4dc6b8 100644 --- a/apps/web/src/router/routeConfig.tsx +++ b/apps/web/src/router/routeConfig.tsx @@ -51,6 +51,7 @@ import { LazyEducation, LazySupport, LazyLanding, + LazyDmca, } from '@/components/ui/LazyComponent'; const LazyPrototype = React.lazy(() => import('@/features/prototype/PrototypePage')); import { PublicRoute } from './PublicRoute'; @@ -115,6 +116,7 @@ export function getPublicStandaloneRoutes(): RouteEntry[] { { path: '/prototype/*', element: }, { path: '/u/:username', element: }, { path: '/playlists/shared/:token', element: }, + { path: '/legal/dmca', element: }, ]; } diff --git a/veza-backend-api/cmd/api/main.go b/veza-backend-api/cmd/api/main.go index 243d47c8e..ee8989b30 100644 --- a/veza-backend-api/cmd/api/main.go +++ b/veza-backend-api/cmd/api/main.go @@ -39,8 +39,8 @@ import ( // @termsOfService http://swagger.io/terms/ // @contact.name API Support -// @contact.url http://www.veza.app/support -// @contact.email support@veza.app +// @contact.url https://veza.fr/support +// @contact.email support@veza.fr // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/veza-backend-api/docs/docs.go b/veza-backend-api/docs/docs.go index c2cb498b7..99bc126dc 100644 --- a/veza-backend-api/docs/docs.go +++ b/veza-backend-api/docs/docs.go @@ -12,8 +12,8 @@ const docTemplate = `{ "termsOfService": "http://swagger.io/terms/", "contact": { "name": "API Support", - "url": "http://www.veza.app/support", - "email": "support@veza.app" + "url": "https://veza.fr/support", + "email": "support@veza.fr" }, "license": { "name": "Apache 2.0", diff --git a/veza-backend-api/docs/swagger.json b/veza-backend-api/docs/swagger.json index 1b7cf0d70..e1f22aada 100644 --- a/veza-backend-api/docs/swagger.json +++ b/veza-backend-api/docs/swagger.json @@ -6,8 +6,8 @@ "termsOfService": "http://swagger.io/terms/", "contact": { "name": "API Support", - "url": "http://www.veza.app/support", - "email": "support@veza.app" + "url": "https://veza.fr/support", + "email": "support@veza.fr" }, "license": { "name": "Apache 2.0", diff --git a/veza-backend-api/docs/swagger.yaml b/veza-backend-api/docs/swagger.yaml index 5ea7c0b66..a2ec9a58c 100644 --- a/veza-backend-api/docs/swagger.yaml +++ b/veza-backend-api/docs/swagger.yaml @@ -1149,9 +1149,9 @@ definitions: host: localhost:18080 info: contact: - email: support@veza.app + email: support@veza.fr name: API Support - url: http://www.veza.app/support + url: https://veza.fr/support description: Backend API for Veza platform. license: name: Apache 2.0