diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 41dd3c56d0..5d8c67a463 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,19 +3,19 @@ on: workflow_call: inputs: environment: - description: 'The Github environment to load secrets from' + description: The Github environment to load secrets from type: string required: true - context: - description: "The Netlify context use when building" + netlify-context: + description: The Netlify context use when building type: string required: true - alias: + netlify-alias: description: The Netlify alias to deploy to (empty deploys to production) type: string required: true sha: - description: "The commit SHA to deploy" + description: The commit SHA to deploy type: string required: true @@ -61,7 +61,7 @@ jobs: run: npm install netlify-cli -g - name: Build using Netlify - run: netlify build --context ${{ inputs.context }} --offline + run: netlify build --context ${{ inputs.netlify-context }} --offline env: NETLIFY_SITE_ID: ${{ vars.NETLIFY_SITE_ID }} NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} @@ -92,16 +92,19 @@ jobs: CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} REALM_GRAPHQL_API_KEY: ${{ secrets.REALM_GRAPHQL_API_KEY }} + GATSBY_COMMIT_SHA: ${{ inputs.sha }} - name: Upload to netlify id: deploy-netlify working-directory: site/gatsby-site run: | set -e - if [[ -z "${{ inputs.alias }}" ]]; then + # If no alias is specified, deploy to production + if [[ -z "${{ inputs.netlify-alias }}" ]]; then OUTPUT=$(bash -c "netlify deploy --json --prod" | tr '\n' ' ') + # Otherwise, deploy to the specified alias else - OUTPUT=$(bash -c "netlify deploy --json --alias=${{ inputs.alias }}" | tr '\n' ' ') + OUTPUT=$(bash -c "netlify deploy --json --alias=${{ inputs.netlify-alias }}" | tr '\n' ' ') fi set +e NETLIFY_OUTPUT=$(echo "$OUTPUT") diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 58036026f7..357759f273 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -5,6 +5,7 @@ on: branches: - staging types: [opened, synchronize, reopened] + jobs: permissions-check: runs-on: ubuntu-latest @@ -33,6 +34,7 @@ jobs: with: sha: ${{ github.event.pull_request.head.sha }} environment: staging + netlify-context: deploy-preview call-test: if: ${{ !failure() }} @@ -53,5 +55,5 @@ jobs: with: sha: ${{ github.event.pull_request.head.sha }} environment: staging - context: deploy-preview - alias: pr-${{ github.event.pull_request.number }} + netlify-context: deploy-preview + netlify-alias: pr-${{ github.event.pull_request.number }} diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 279573b068..33094ac898 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -4,6 +4,7 @@ on: push: branches: - staging + jobs: call-realm: @@ -19,6 +20,7 @@ jobs: with: sha: ${{ github.sha }} environment: staging + netlify-context: production call-test: uses: ./.github/workflows/test.yml @@ -37,5 +39,5 @@ jobs: with: environment: staging sha: ${{ github.sha }} - context: production - alias: + netlify-context: production + netlify-alias: diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index dccbace44b..e9a685ed1b 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -10,6 +10,10 @@ on: description: 'The SHA of the commit to build' type: string required: true + netlify-context: + description: The Netlify context use when building + type: string + required: true jobs: test: @@ -51,7 +55,7 @@ jobs: run: npm install netlify-cli -g - name: Build using Netlify - run: netlify build --context deploy-preview --offline + run: netlify build --context ${{ inputs.netlify-context }} --offline working-directory: site/gatsby-site env: INSTRUMENT: true @@ -84,6 +88,7 @@ jobs: CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} REALM_GRAPHQL_API_KEY: ${{ secrets.REALM_GRAPHQL_API_KEY }} + GATSBY_COMMIT_SHA: ${{ inputs.sha }} - name: Cache build uses: actions/cache/save@v3 diff --git a/README.md b/README.md index 8de84e38e8..8116849554 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,18 @@

+

Artificial Intelligence Incident Database

-[![Netlify Status](https://api.netlify.com/api/v1/badges/9eb0dda2-916c-46f9-a0bd-9ddab3879c6e/deploy-status)](https://app.netlify.com/sites/aiid/deploys) -[![Slack Link](https://img.shields.io/badge/Join%20the%20RAIC%20Slack!-purple?logo=slack)](https://forms.gle/v7UHJvEkYSJQ7jHj7) +

+ +   + +   + +

Information about the goals and organization of the AI Incident Database can be found on the [production website](https://incidentdatabase.ai/). This page concentrates on onboarding for the following types of contributions to the database, diff --git a/site/gatsby-site/blog/deepfakes-child-safety/index.es.mdx b/site/gatsby-site/blog/deepfakes-child-safety/index.es.mdx index 9ed57828b0..c8ec87671c 100644 --- a/site/gatsby-site/blog/deepfakes-child-safety/index.es.mdx +++ b/site/gatsby-site/blog/deepfakes-child-safety/index.es.mdx @@ -11,9 +11,9 @@ aiTranslated: true **AVISO LEGAL:** Esta publicación no es un consejo o comentario legal y no debe interpretarse como tal. -En 2023 se produjo un aumento de los materiales de abuso sexual infantil (CSAM) generados por IA, junto con procesamientos de los infractores, una variedad de intentos legislativos para combatir los deepfakes de IA dirigidos a menores y la [orden ejecutiva sobre inteligencia artificial de la administración Biden](https://www.whitehouse.gov/briefing-room/presidential-actions/2023/10/30/executive-order-on-the-safe-secure-and-trustworthy-development-and-use-of-artificial-intelligence/). +En 2023 se produjo un aumento de los materiales de abuso sexual infantil (MASI) generados por IA, junto con procesamientos de los infractores, una variedad de intentos legislativos para combatir los deepfakes de IA dirigidos a menores y la [orden ejecutiva sobre inteligencia artificial de la administración Biden](https://www.whitehouse.gov/briefing-room/presidential-actions/2023/10/30/executive-order-on-the-safe-secure-and-trustworthy-development-and-use-of-artificial-intelligence/). -Los deepfakes se pueden clasificar en términos generales en dos categorías principales, cada una con su propio subconjunto relacionado con CSAM. La primera categoría incluye deepfakes de individuos reales, donde el daño predominante asociado con CSAM surge de la generación de pornografía deepfake con niños reales. La segunda categoría abarca los deepfakes en los que los sujetos son completamente virtuales pero convincentemente realistas. En esta categoría, las preocupaciones sobre CSAM están relacionadas principalmente con la creación de medios audiovisuales sintéticos inapropiados que representan niños virtuales. En conjunto, estas dos categorías taxonómicas demuestran las diversas formas preocupantes en que se puede emplear la tecnología deepfake, especialmente en la generación y proliferación de CSAM. +Los deepfakes se pueden clasificar en términos generales en dos categorías principales, cada una con su propio subconjunto relacionado con MASI. La primera categoría incluye deepfakes de individuos reales, donde el daño predominante asociado con MASI surge de la generación de pornografía deepfake con niños reales. La segunda categoría abarca los deepfakes en los que los sujetos son completamente virtuales pero convincentemente realistas. En esta categoría, las preocupaciones sobre MASI están relacionadas principalmente con la creación de medios audiovisuales sintéticos inapropiados que representan niños virtuales. En conjunto, estas dos categorías taxonómicas demuestran las diversas formas preocupantes en que se puede emplear la tecnología deepfake, especialmente en la generación y proliferación de MASI. Este artículo proporciona una instantánea de parte del trabajo de la base de datos de incidentes de IA en el seguimiento de estos incidentes emergentes, junto con un estudio de algunas de las respuestas legislativas incipientes. @@ -37,9 +37,9 @@ Recientemente, [un incidente](https://incidentdatabase.ai/cite/576/) salió a la *The Wall Street Journal* también [informado recientemente](https://www.wsj.com/tech/facebook-and-instagram-steer-predators-to-children-new-mexico-attorney-general-alleges-in-demand-b76a5b04?mod=Searchresults_pos1&page=1) sobre el Fiscal General de Nuevo México que presentó una demanda contra Meta, alegando que los algoritmos de Facebook e Instagram dirigieron a los depredadores y al contenido pornográfico a cuentas de prueba de temas menores. La investigación involucró imágenes de niños ficticios generadas por IA, lo que resultó en que las cuentas recibieran mensajes explícitos y proposiciones sexuales. La demanda afirma que las plataformas de Meta se han convertido en un mercado para depredadores y critica su falta de protección a los usuarios menores de edad, citando varios casos penales de explotación a través de estas plataformas. En este caso, fueron los investigadores quienes generaron las imágenes de los menores ficticios, adaptando las nuevas tecnologías a antiguas técnicas en este ámbito específico de la aplicación de la ley. -Un [estudio reciente](https://stacks.stanford.edu/file/druid:kh752sm9123/ml_training_data_csam_report-2023-12-21.pdf) realizado por David Thiel del Stanford Internet Observatory detalla la presencia de CSAM en los datos de entrenamiento de Modelos generativos de aprendizaje automático, centrándose en el conjunto de datos LAION-5B utilizado para modelos como Difusión estable. A través de varios métodos, incluidos los clasificadores PhotoDNA y ML, Thiel identificó numerosos casos nuevos y conocidos de CSAM en el conjunto de datos. Los hallazgos son oportunos ya que muestran la necesidad de prácticas de capacitación de modelos y curación de datos más rigurosas para evitar la perpetuación de contenido dañino, en línea con las preocupaciones planteadas por los incidentes en las plataformas de redes sociales y enfatizando la importancia de un mayor desarrollo responsable de la IA en este sentido. frente. +Un [estudio reciente](https://stacks.stanford.edu/file/druid:kh752sm9123/ml_training_data_csam_report-2023-12-21.pdf) realizado por David Thiel del Stanford Internet Observatory detalla la presencia de MASI en los datos de entrenamiento de Modelos generativos de aprendizaje automático, centrándose en el conjunto de datos LAION-5B utilizado para modelos como Difusión estable. A través de varios métodos, incluidos los clasificadores PhotoDNA y ML, Thiel identificó numerosos casos nuevos y conocidos de MASI en el conjunto de datos. Los hallazgos son oportunos ya que muestran la necesidad de prácticas de capacitación de modelos y curación de datos más rigurosas para evitar la perpetuación de contenido dañino, en línea con las preocupaciones planteadas por los incidentes en las plataformas de redes sociales y enfatizando la importancia de un mayor desarrollo responsable de la IA en este sentido. frente. -Actualmente, los esfuerzos legales para abordar los deepfakes de CSAM han sido reactivos y poco sistemáticos. Sin embargo, la orden ejecutiva del presidente Biden sobre la IA tiene como objetivo establecer normas estrictas para prevenir el uso indebido de la IA, centrándose en la seguridad nacional y la seguridad individual, lo que implica autenticar el contenido digital y etiquetar los medios sintéticos, especialmente para proteger a los niños de los daños provocados por la IA. Los desarrolladores deben compartir los resultados de las pruebas de seguridad de la IA antes de su uso público, centrándose en problemas como la creación de CSAM. La orden dirige el desarrollo de estándares para la autenticación de contenido y la detección de IA, y aborda el CSAM generado por IA y las imágenes sexualizadas no consensuales. Antes de la orden ejecutiva, [U.S. Los fiscales generales instaron al Congreso](https://www.scag.gov/media/pvehppkm/54-state-ags-urge-study-of-ai-and-harmful-impacts-on-children.pdf) a investigar el papel de la IA. en la explotación infantil, enfatizando la necesidad de una legislación integral sobre privacidad de datos. +Actualmente, los esfuerzos legales para abordar los deepfakes de MASI han sido reactivos y poco sistemáticos. Sin embargo, la orden ejecutiva del presidente Biden sobre la IA tiene como objetivo establecer normas estrictas para prevenir el uso indebido de la IA, centrándose en la seguridad nacional y la seguridad individual, lo que implica autenticar el contenido digital y etiquetar los medios sintéticos, especialmente para proteger a los niños de los daños provocados por la IA. Los desarrolladores deben compartir los resultados de las pruebas de seguridad de la IA antes de su uso público, centrándose en problemas como la creación de MASI. La orden dirige el desarrollo de estándares para la autenticación de contenido y la detección de IA, y aborda el MASI generado por IA y las imágenes sexualizadas no consensuales. Antes de la orden ejecutiva, [U.S. Los fiscales generales instaron al Congreso](https://www.scag.gov/media/pvehppkm/54-state-ags-urge-study-of-ai-and-harmful-impacts-on-children.pdf) a investigar el papel de la IA. en la explotación infantil, enfatizando la necesidad de una legislación integral sobre privacidad de datos. Hasta el momento, [no existe ningún proyecto de ley federal general](https://www.nbcnews.com/news/us-news/little-recourse-teens-girls-victimized-ai-deepfake-nudes-rcna126399), pero se han realizado esfuerzos. (por ejemplo, [Ley de Responsabilidad H.R.3230 DEEP FAKES](https://www.congress.gov/bill/116th-congress/house-bill/3230)). A continuación se muestran cuatro ejemplos de legislación a nivel estatal: @@ -51,4 +51,4 @@ Hasta el momento, [no existe ningún proyecto de ley federal general](https://ww * [Virginia, Código 18.2-386.2](https://law.lis.virginia.gov/vacode/title18.2/chapter8/section18.2-386.2/): convierte en un delito menor de Clase 1 compartir o vender desnudos maliciosamente o imágenes sexualmente explícitas de alguien sin su consentimiento, especialmente si se hacen para acosar, coaccionar o intimidar. Esto incluye imágenes que han sido alteradas digitalmente para representar a una persona. Los proveedores de servicios de Internet no se hacen responsables del contenido compartido por otros. Se pueden emprender acciones legales donde se produjo el hecho ilícito o donde se manipuló la imagen. También pueden aplicarse otros cargos legales. -En la base de datos de incidentes de IA (AIID), hemos estado catalogando e investigando con preocupación estos incidentes recientes de CSAM. Como toda tecnología, la IA generativa plantea riesgos y oportunidades, y los riesgos para los niños en este caso son graves. Si desea unirse a nosotros en nuestra misión de documentar incidentes de IA con el objetivo de aprender de los errores del pasado para mitigar riesgos futuros, puede conectarse con nosotros a través de nuestra página de [contacto](https://incidentdatabase.ai/contact/) . Agradecemos los envíos que informen sobre todos y cada uno de los incidentes de IA utilizando nuestra página [envío](https://incidentdatabase.ai/apps/submit/); sin embargo, tenga en cuenta que, si bien rastreamos y analizamos activamente las tendencias e incidentes de CSAM, el AIID no es el destino directo para informar sobre CSAM real. Dirija la denuncia de CSAM al Departamento de Justicia [Sección de Obscenidad y Explotación Infantil](https://www.justice.gov/criminal/criminal-ceos/report-violations). \ No newline at end of file +En la base de datos de incidentes de IA (AIID), hemos estado catalogando e investigando con preocupación estos incidentes recientes de MASI. Como toda tecnología, la IA generativa plantea riesgos y oportunidades, y los riesgos para los niños en este caso son graves. Si desea unirse a nosotros en nuestra misión de documentar incidentes de IA con el objetivo de aprender de los errores del pasado para mitigar riesgos futuros, puede conectarse con nosotros a través de nuestra página de [contacto](https://incidentdatabase.ai/contact/) . Agradecemos los envíos que informen sobre todos y cada uno de los incidentes de IA utilizando nuestra página [envío](https://incidentdatabase.ai/apps/submit/); sin embargo, tenga en cuenta que, si bien rastreamos y analizamos activamente las tendencias e incidentes de MASI, el AIID no es el destino directo para informar sobre MASI real. Dirija la denuncia de MASI al Departamento de Justicia [Sección de Obscenidad y Explotación Infantil](https://www.justice.gov/criminal/criminal-ceos/report-violations). \ No newline at end of file diff --git a/site/gatsby-site/blog/deepfakes-child-safety/index.mdx b/site/gatsby-site/blog/deepfakes-child-safety/index.mdx index e8cad11d2b..c2314479fd 100644 --- a/site/gatsby-site/blog/deepfakes-child-safety/index.mdx +++ b/site/gatsby-site/blog/deepfakes-child-safety/index.mdx @@ -10,7 +10,7 @@ slug: '/blog/deepfakes-and-child-safety' **DISCLAIMER:** This post is not legal advice or commentary and should not be construed as such. -2023 saw an increase in AI-generated child sex abuse materials (CSAM), along with prosecutions of offenders, a variety of legislative attempts to combat AI deepfakes targeting minors, and the Biden administration's [executive order on artificial intelligence](https://www.whitehouse.gov/briefing-room/presidential-actions/2023/10/30/executive-order-on-the-safe-secure-and-trustworthy-development-and-use-of-artificial-intelligence/). +2023 saw an increase in AI-generated child sexual abuse materials (CSAM), along with prosecutions of offenders, a variety of legislative attempts to combat AI deepfakes targeting minors, and the Biden administration's [executive order on artificial intelligence](https://www.whitehouse.gov/briefing-room/presidential-actions/2023/10/30/executive-order-on-the-safe-secure-and-trustworthy-development-and-use-of-artificial-intelligence/). Deepfakes can be broadly classified into two main categories, each with its own subset related to CSAM. The first category includes deepfakes of actual individuals, where the predominant harm associated with CSAM arises from the generation of deepfake pornography featuring real children. The second category encompasses deepfakes where the subjects are entirely virtual yet convincingly realistic. In this category, CSAM concerns are primarily linked to the creation of inappropriate synthetic audiovisual media depicting virtual children. Collectively, these two taxonomic categories demonstrate the various troubling ways deepfake technology can be employed, especially in the generation and proliferation of CSAM. diff --git a/site/gatsby-site/cypress/e2e/incidentVariants.cy.js b/site/gatsby-site/cypress/e2e/incidentVariants.cy.js index c02e029fba..1f867e3e6c 100644 --- a/site/gatsby-site/cypress/e2e/incidentVariants.cy.js +++ b/site/gatsby-site/cypress/e2e/incidentVariants.cy.js @@ -66,12 +66,12 @@ describe('Variants pages', () => { cy.disableSmoothScroll(); }); - it('Should display Variant list', async () => { + it('Should display Variant list', () => { cy.visit(url); cy.contains('h1', 'Variants').should('exist').scrollIntoView(); - getVariants(async (variants) => { + getVariants((variants) => { cy.get('[data-cy=variant-card]').should('have.length', variants.length); for (let index = 0; index < variants.length; index++) { @@ -79,7 +79,7 @@ describe('Variants pages', () => { cy.get('[data-cy=variant-card]') .eq(index) - .within(async () => { + .within(() => { cy.get('[data-cy=variant-status-badge]').contains( getVariantStatusText(getVariantStatus(variant)) ); diff --git a/site/gatsby-site/cypress/e2e/integration/apps/checklistsForm.cy.js b/site/gatsby-site/cypress/e2e/integration/apps/checklistsForm.cy.js index 137704ae17..5e6bfdfdb3 100644 --- a/site/gatsby-site/cypress/e2e/integration/apps/checklistsForm.cy.js +++ b/site/gatsby-site/cypress/e2e/integration/apps/checklistsForm.cy.js @@ -110,6 +110,24 @@ describe('Checklists App Form', () => { }); }); + maybeIt('Should trigger GraphQL upsert query on adding tag', () => { + withLogin(({ user }) => { + interceptFindChecklist({ ...defaultChecklist, owner_id: user.userId }); + interceptUpsertChecklist({}); + + cy.visit(url); + + cy.get('#tags_goals_input').type('Code Generation'); + cy.get('#tags_goals').contains('Code Generation').click(); + + cy.wait(['@upsertChecklist']).then((xhr) => { + expect(xhr.request.body.variables.checklist).to.deep.nested.include({ + tags_goals: ['GMF:Known AI Goal:Code Generation'], + }); + }); + }); + }); + maybeIt('Should trigger GraphQL update on removing tag', () => { withLogin(({ user }) => { interceptFindChecklist({ diff --git a/site/gatsby-site/cypress/e2e/integration/apps/submitted.cy.js b/site/gatsby-site/cypress/e2e/integration/apps/submitted.cy.js index 3c3c619002..3299ce4785 100644 --- a/site/gatsby-site/cypress/e2e/integration/apps/submitted.cy.js +++ b/site/gatsby-site/cypress/e2e/integration/apps/submitted.cy.js @@ -872,7 +872,7 @@ describe('Submitted reports', () => { cy.get('[data-cy="promote-button"]').click(); - cy.contains('[data-cy="toast"]', 'Description is required.').should('exist'); + cy.contains('[data-cy="toast"]', 'Description is required').should('exist'); cy.wait('@promotionInvoked', { timeout: 2000 }); } diff --git a/site/gatsby-site/cypress/e2e/integration/landingPage.cy.js b/site/gatsby-site/cypress/e2e/integration/landingPage.cy.js index 0c389a8e99..23453a4a54 100644 --- a/site/gatsby-site/cypress/e2e/integration/landingPage.cy.js +++ b/site/gatsby-site/cypress/e2e/integration/landingPage.cy.js @@ -175,4 +175,10 @@ describe('The Landing page', () => { cy.get('[data-cy="random-incidents-carousel-item"]').should('have.length', 5); }); + + it('Renders commit sha in the footer', () => { + cy.visit('/'); + + cy.get('[data-cy="commit-sha"]').should('be.visible'); + }); }); diff --git a/site/gatsby-site/i18n/locales/es/validation.json b/site/gatsby-site/i18n/locales/es/validation.json index 435f4d8984..778cf63f7c 100644 --- a/site/gatsby-site/i18n/locales/es/validation.json +++ b/site/gatsby-site/i18n/locales/es/validation.json @@ -13,5 +13,26 @@ "Please review report. Some data is missing.": "Por favor revisa el reporte. Faltan algunos datos.", "Please review submission. Some data is missing.": "Por favor revisa el incidente. Faltan algunos datos.", "Some data is missing.": "Faltan algunos datos.", - "Please review. Some data is missing.": "Por favor revisa el formulario. Faltan algunos datos." + "Please review. Some data is missing.": "Por favor revisa el formulario. Faltan algunos datos.", + "*Title must have at least 6 characters": "*El título debe tener al menos 6 caracteres", + "*Titles can't be longer than 500 characters": "*Los títulos no pueden tener más de 500 caracteres", + "Alleged Developer must have at least 3 characters": "El desarrollador presunto debe tener al menos 3 caracteres", + "Alleged Developers can't be longer than 200 characters": "Los desarrolladores presuntos no pueden tener más de 200 caracteres", + "Alleged Deployers must have at least 3 characters": "Los implementadores presuntos deben tener al menos 3 caracteres", + "Alleged Deployers can't be longer than 200 characters": "Los implementadores presuntos no pueden tener más de 200 caracteres", + "Harmed Parties must have at least 3 characters": "Las partes perjudicadas deben tener al menos 3 caracteres", + "Harmed Parties can't be longer than 200 characters": "Las partes perjudicadas no pueden tener más de 200 caracteres", + "Description must have at least 3 characters": "La descripción debe tener al menos 3 caracteres", + "Description can't be longer than 500 characters": "La descripción no puede tener más de 500 caracteres", + "*Incident title is required": "*El título del incidente es obligatorio", + "*Alleged developers is required": "*Se requiere el desarrollador presunto del sistema de IA", + "*Alleged developer of AI system is required": "*Se requiere el desarrollador presunto del sistema de IA", + "*Alleged deployers is required": "*Se requiere el implementador presunto del sistema de IA", + "*Alleged deployer of AI system is required": "*Se requiere el implementador presunto del sistema de IA", + "*Alleged Harmed Parties is required": "*Se requieren las partes presuntamente perjudicadas o casi perjudicadas", + "*Alleged harmed or nearly harmed parties is required": "*Se requieren las partes presuntamente perjudicadas o casi perjudicadas", + "*Description is required": "*La descripción es obligatoria", + "*Incident Date is required": "*Fecha del incidente es obligatoria", + "*Incident Date required": "*Fecha del incidente es obligatoria", + "*Incident ID(s) must be a number": "*El ID del incidente debe ser un número" } diff --git a/site/gatsby-site/i18n/locales/fr/validation.json b/site/gatsby-site/i18n/locales/fr/validation.json index f22ed25e6a..1701f0da92 100644 --- a/site/gatsby-site/i18n/locales/fr/validation.json +++ b/site/gatsby-site/i18n/locales/fr/validation.json @@ -7,5 +7,26 @@ "*Must enter URL in http://www.example.com/images/preview.png format": "*Vous devez entrer l'URL avec le format http://www.example.com/images/preview.png", "Incident ID {{value}} not found!": "Incident {{value}} introuvable !", "Incident ID": "ID de l'incident", - "Type and press Enter to add an item": "Ecrivez et appuyez Enter pour ajouter un élément" + "Type and press Enter to add an item": "Ecrivez et appuyez Enter pour ajouter un élément", + "*Title must have at least 6 characters": "*Le titre doit comporter au moins 6 caractères", + "*Titles can't be longer than 500 characters": "*Les titres ne peuvent pas comporter plus de 500 caractères", + "Alleged Developer must have at least 3 characters": "Le développeur présumé doit avoir au moins 3 caractères", + "Alleged Developers can't be longer than 200 characters": "Les développeurs présumés ne peuvent pas comporter plus de 200 caractères", + "Alleged Deployers must have at least 3 characters": "Les implémenteurs présumés doivent avoir au moins 3 caractères", + "Alleged Deployers can't be longer than 200 characters": "Les implémenteurs présumés ne peuvent pas comporter plus de 200 caractères", + "Harmed Parties must have at least 3 characters": "Les parties lésées doivent avoir au moins 3 caractères", + "Harmed Parties can't be longer than 200 characters": "Les parties lésées ne peuvent pas comporter plus de 200 caractères", + "Description must have at least 3 characters": "La description doit comporter au moins 3 caractères", + "Description can't be longer than 500 characters": "La description ne peut pas comporter plus de 500 caractères", + "*Incident title is required": "*Le titre de l'incident est requis", + "*Alleged developers is required": "*Le développeur présumé du système d'IA est requis", + "*Alleged developer of AI system is required": "*Le développeur présumé du système d'IA est requis", + "*Alleged deployers is required": "*Le déploiement présumé du système d'IA est requis", + "*Alleged deployer of AI system is required": "*Le déploiement présumé du système d'IA est requis", + "*Alleged Harmed Parties is required": "*Les parties présumées lésées ou presque lésées sont requises", + "*Alleged harmed or nearly harmed parties is required": "*Les parties présumées lésées ou presque lésées sont requises", + "*Description is required": "*La description est requise", + "*Incident Date is required": "*Date de l'incident requise", + "*Incident Date required": "*Date de l'incident requise", + "*Incident ID(s) must be a number": "*L'ID de l'incident doit être un nombre" } diff --git a/site/gatsby-site/package-lock.json b/site/gatsby-site/package-lock.json index ce7d93b49f..c0330fef4b 100644 --- a/site/gatsby-site/package-lock.json +++ b/site/gatsby-site/package-lock.json @@ -24,6 +24,7 @@ "@graphql-tools/schema": "^8.3.3", "@graphql-tools/wrap": "^8.4.6", "@mdx-js/react": "^2.3.0", + "@parcel/watcher-linux-x64-glibc": "*", "@postlight/parser": "^2.2.3", "@prismicio/react": "^2.7.1", "algoliasearch": "^4.20.0", @@ -131,6 +132,9 @@ "prism-react-renderer": "^1.2.0", "start-server-and-test": "^1.14.0", "tailwindcss": "^3.3.2" + }, + "optionalDependencies": { + "@parcel/watcher-linux-x64-glibc": "^2.4.0" } }, "node_modules/@algolia/cache-browser-local-storage": { @@ -7628,9 +7632,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.2.0.tgz", - "integrity": "sha512-xJvJ7R2wJdi47WZBFS691RDOWvP1j/IAs3EXaWVhDI8FFITbWrWaln7KoNcR0Y3T+ZwimFY/cfb0PNht1q895g==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.0.tgz", + "integrity": "sha512-KphV8awJmxU3q52JQvJot0QMu07CIyEjV+2Tb2ZtbucEgqyRcxOBDMsqp1JNq5nuDXtcCC0uHQICeiEz38dPBQ==", "cpu": [ "x64" ], @@ -7703,6 +7707,25 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.2.0.tgz", + "integrity": "sha512-xJvJ7R2wJdi47WZBFS691RDOWvP1j/IAs3EXaWVhDI8FFITbWrWaln7KoNcR0Y3T+ZwimFY/cfb0PNht1q895g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@parcel/watcher/node_modules/node-addon-api": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", diff --git a/site/gatsby-site/package.json b/site/gatsby-site/package.json index 794393392f..f6bd6cb6df 100644 --- a/site/gatsby-site/package.json +++ b/site/gatsby-site/package.json @@ -158,5 +158,8 @@ "overrides": { "minimist": "1.2.8", "d3-color": "3.1.0" + }, + "optionalDependencies": { + "@parcel/watcher-linux-x64-glibc": "^2.4.0" } } diff --git a/site/gatsby-site/src/components/checklists/CheckListForm.js b/site/gatsby-site/src/components/checklists/CheckListForm.js index 84d5978ce7..efd2fb752e 100644 --- a/site/gatsby-site/src/components/checklists/CheckListForm.js +++ b/site/gatsby-site/src/components/checklists/CheckListForm.js @@ -288,6 +288,7 @@ const QueryTagInput = ({ include(tag.split(':')))} onChange={(tagInputArray) => { diff --git a/site/gatsby-site/src/components/layout/Footer.js b/site/gatsby-site/src/components/layout/Footer.js index 442e239d0a..399676148e 100644 --- a/site/gatsby-site/src/components/layout/Footer.js +++ b/site/gatsby-site/src/components/layout/Footer.js @@ -115,7 +115,7 @@ export default function Footer() { id="main-footer" className="bg-text-light-gray relative sm:grid sm:grid-cols-2 md:grid-cols-4 gap-5 p-5 z-50" > - {footerContent.map((group) => { + {footerContent.map((group, i) => { const title = group.title; const items = group.items; @@ -203,6 +203,14 @@ export default function Footer() { })} )} + + {i == footerContent.length - 1 && process.env.GATSBY_COMMIT_SHA && ( +
  • +
    + {process.env.GATSBY_COMMIT_SHA.toString().substring(0, 7)} +
    +
  • + )} ); @@ -210,7 +218,7 @@ export default function Footer() { {allPrismicFooter.edges.length <= 0 && (
    -

    2023 - AI Incident Database

    +

    2024 - AI Incident Database

    Terms of use diff --git a/site/gatsby-site/src/components/submissions/SubmissionEditForm.js b/site/gatsby-site/src/components/submissions/SubmissionEditForm.js index a408c69103..b7d722d5b3 100644 --- a/site/gatsby-site/src/components/submissions/SubmissionEditForm.js +++ b/site/gatsby-site/src/components/submissions/SubmissionEditForm.js @@ -55,7 +55,7 @@ const SubmissionEditForm = ({ handleSubmit, saving, setSaving, userLoading, user const addToast = useToastContext(); - const { i18n, t } = useTranslation(['submitted']); + const { i18n, t } = useTranslation(['submitted', 'validation']); const [promoteSubmissionToReport] = useMutation(PROMOTE_SUBMISSION, { fetchPolicy: 'network-only', diff --git a/site/gatsby-site/src/components/submissions/schemas.js b/site/gatsby-site/src/components/submissions/schemas.js index 59eec76bd3..28b4500205 100644 --- a/site/gatsby-site/src/components/submissions/schemas.js +++ b/site/gatsby-site/src/components/submissions/schemas.js @@ -3,6 +3,8 @@ import { dateRegExp, isPastDate } from '../../utils/date'; const incident_title = yup .string() + .nullable() + .default('') .min(6, '*Title must have at least 6 characters') .max(500, "*Titles can't be longer than 500 characters"); @@ -36,6 +38,8 @@ const incident_date = yup const description = yup .string() + .nullable() + .default('') .matches(/^.{3,}/, { excludeEmptyString: true, message: 'Description must have at least 3 characters', @@ -139,17 +143,17 @@ export const schema = yup.object().shape({ }); export const incidentSchema = schema.shape({ - incident_title: incident_title.required('*Incident Title is required.'), - developers: developers.required(), - deployers: deployers.required(), - harmed_parties: harmed_parties.required(), - description: description.required('*Description is required.'), + incident_title: incident_title.required('*Incident Title is required'), + developers: developers.required('*Alleged developer of AI system is required'), + deployers: deployers.required('*Alleged deployer of AI system is required'), + harmed_parties: harmed_parties.required('*Alleged harmed or nearly harmed parties is required'), + description: description.required('*Description is required'), incident_date: incident_date.required('*Incident Date required'), incident_ids: yup.mixed(), }); export const reportSchema = schema.shape({ - incident_ids: incident_ids.required('*Must be a number'), + incident_ids: incident_ids.required('*Incident ID(s) must be a number'), }); export const issueSchema = schema.shape({ diff --git a/site/gatsby-site/src/pages/apps/checklists.js b/site/gatsby-site/src/pages/apps/checklists.js index 2627bc69d7..2f2498eb70 100644 --- a/site/gatsby-site/src/pages/apps/checklists.js +++ b/site/gatsby-site/src/pages/apps/checklists.js @@ -6,6 +6,7 @@ import { Formik } from 'formik'; import { graphql } from 'gatsby'; import { useQueryParams, StringParam } from 'use-query-params'; import { useQuery, useMutation } from '@apollo/client'; +import { LocalizedLink } from 'plugins/gatsby-theme-i18n'; import AiidHelmet from 'components/AiidHelmet'; import CheckListForm from 'components/checklists/CheckListForm'; @@ -105,13 +106,19 @@ const ChecklistsPageBody = ({ taxa, classifications, users }) => { } if (query.id && savedChecklistLoading) { return ; - } - if (query.id && savedChecklist) { + } else if (query.id && savedChecklistData && savedChecklist) { return ( {(FormProps) => } ); + } else if (query.id && savedChecklistData && !savedChecklist) { + return ( +

    + No checklist with id {query.id}.{' '} + Return to checklists. +

    + ); } }; diff --git a/site/gatsby-site/tests-netlify.toml b/site/gatsby-site/tests-netlify.toml index 34dd199623..c97bd6992b 100644 --- a/site/gatsby-site/tests-netlify.toml +++ b/site/gatsby-site/tests-netlify.toml @@ -1,8 +1,9 @@ +[build] + base = "/site/gatsby-site" + publish = "public" + [[plugins]] package = "@netlify/plugin-gatsby" [build.processing.html] - pretty_urls = false - -[context.deploy-preview] - publish = "public/" \ No newline at end of file + pretty_urls = false \ No newline at end of file diff --git a/site/realm/functions/config.json b/site/realm/functions/config.json index 7285547529..258a608b1f 100644 --- a/site/realm/functions/config.json +++ b/site/realm/functions/config.json @@ -43,6 +43,26 @@ "name": "logReportHistory", "private": false }, + { + "name": "onNewEntryFunction_aiidprod", + "private": true + }, + { + "name": "onNewEntryFunction_customData", + "private": true + }, + { + "name": "onNewEntryFunction_history", + "private": true + }, + { + "name": "onNewEntryFunction_translations", + "private": true + }, + { + "name": "setCreatedAtField", + "private": true + }, { "name": "sendEmail", "private": false @@ -111,4 +131,4 @@ "name": "logIncidentHistory", "private": false } -] +] \ No newline at end of file diff --git a/site/realm/functions/onNewEntryFunction_aiidprod.js b/site/realm/functions/onNewEntryFunction_aiidprod.js new file mode 100644 index 0000000000..06f959b064 --- /dev/null +++ b/site/realm/functions/onNewEntryFunction_aiidprod.js @@ -0,0 +1,3 @@ +exports = function (changeEvent) { + context.functions.execute('setCreatedAtField', { changeEvent, dbName: "aiidprod" }); +}; \ No newline at end of file diff --git a/site/realm/functions/onNewEntryFunction_customData.js b/site/realm/functions/onNewEntryFunction_customData.js new file mode 100644 index 0000000000..62f34ab057 --- /dev/null +++ b/site/realm/functions/onNewEntryFunction_customData.js @@ -0,0 +1,3 @@ +exports = function (changeEvent) { + context.functions.execute('setCreatedAtField', { changeEvent, dbName: "customData" }); +}; \ No newline at end of file diff --git a/site/realm/functions/onNewEntryFunction_history.js b/site/realm/functions/onNewEntryFunction_history.js new file mode 100644 index 0000000000..ef7ffb07e6 --- /dev/null +++ b/site/realm/functions/onNewEntryFunction_history.js @@ -0,0 +1,3 @@ +exports = function (changeEvent) { + context.functions.execute('setCreatedAtField', { changeEvent, dbName: "history" }); +}; \ No newline at end of file diff --git a/site/realm/functions/onNewEntryFunction_translations.js b/site/realm/functions/onNewEntryFunction_translations.js new file mode 100644 index 0000000000..4f227edcc8 --- /dev/null +++ b/site/realm/functions/onNewEntryFunction_translations.js @@ -0,0 +1,3 @@ +exports = function (changeEvent) { + context.functions.execute('setCreatedAtField', { changeEvent, dbName: "translations" }); +}; \ No newline at end of file diff --git a/site/realm/functions/setCreatedAtField.js b/site/realm/functions/setCreatedAtField.js new file mode 100644 index 0000000000..1b21fa1eaa --- /dev/null +++ b/site/realm/functions/setCreatedAtField.js @@ -0,0 +1,7 @@ +exports = async function ({ changeEvent, dbName }) { + const newDocument = changeEvent.fullDocument; + const collectionName = changeEvent.ns.coll; // Get collection name from the event + newDocument.created_at = new Date(); + const collection = context.services.get("mongodb-atlas").db(dbName).collection(collectionName); + collection.updateOne({ _id: newDocument._id }, { $set: { created_at: newDocument.created_at } }); +}; \ No newline at end of file diff --git a/site/realm/triggers/onNewEntry_aiidprod.json b/site/realm/triggers/onNewEntry_aiidprod.json new file mode 100644 index 0000000000..f6c474f112 --- /dev/null +++ b/site/realm/triggers/onNewEntry_aiidprod.json @@ -0,0 +1,28 @@ +{ + "name": "onNewEntry_aiidprod", + "type": "DATABASE", + "disabled": false, + "config": { + "collection": "", + "database": "aiidprod", + "full_document": true, + "full_document_before_change": false, + "match": {}, + "maximum_throughput": false, + "operation_types": [ + "INSERT" + ], + "project": {}, + "service_name": "mongodb-atlas", + "skip_catchup_events": false, + "tolerate_resume_errors": false, + "unordered": false + }, + "event_processors": { + "FUNCTION": { + "config": { + "function_name": "onNewEntryFunction_aiidprod" + } + } + } +} \ No newline at end of file diff --git a/site/realm/triggers/onNewEntry_customData.json b/site/realm/triggers/onNewEntry_customData.json new file mode 100644 index 0000000000..45e90fac76 --- /dev/null +++ b/site/realm/triggers/onNewEntry_customData.json @@ -0,0 +1,28 @@ +{ + "name": "onNewEntry_customData", + "type": "DATABASE", + "disabled": false, + "config": { + "collection": "", + "database": "customData", + "full_document": true, + "full_document_before_change": false, + "match": {}, + "maximum_throughput": false, + "operation_types": [ + "INSERT" + ], + "project": {}, + "service_name": "mongodb-atlas", + "skip_catchup_events": false, + "tolerate_resume_errors": false, + "unordered": false + }, + "event_processors": { + "FUNCTION": { + "config": { + "function_name": "onNewEntryFunction_customData" + } + } + } +} \ No newline at end of file diff --git a/site/realm/triggers/onNewEntry_history.json b/site/realm/triggers/onNewEntry_history.json new file mode 100644 index 0000000000..ec89b17bf8 --- /dev/null +++ b/site/realm/triggers/onNewEntry_history.json @@ -0,0 +1,28 @@ +{ + "name": "onNewEntry_history", + "type": "DATABASE", + "disabled": false, + "config": { + "collection": "", + "database": "history", + "full_document": true, + "full_document_before_change": false, + "match": {}, + "maximum_throughput": false, + "operation_types": [ + "INSERT" + ], + "project": {}, + "service_name": "mongodb-atlas", + "skip_catchup_events": false, + "tolerate_resume_errors": false, + "unordered": false + }, + "event_processors": { + "FUNCTION": { + "config": { + "function_name": "onNewEntryFunction_history" + } + } + } +} \ No newline at end of file diff --git a/site/realm/triggers/onNewEntry_translations.json b/site/realm/triggers/onNewEntry_translations.json new file mode 100644 index 0000000000..5c4f339ef7 --- /dev/null +++ b/site/realm/triggers/onNewEntry_translations.json @@ -0,0 +1,28 @@ +{ + "name": "onNewEntry_translations", + "type": "DATABASE", + "disabled": false, + "config": { + "collection": "", + "database": "translations", + "full_document": true, + "full_document_before_change": false, + "match": {}, + "maximum_throughput": false, + "operation_types": [ + "INSERT" + ], + "project": {}, + "service_name": "mongodb-atlas", + "skip_catchup_events": false, + "tolerate_resume_errors": false, + "unordered": false + }, + "event_processors": { + "FUNCTION": { + "config": { + "function_name": "onNewEntryFunction_translations" + } + } + } +} \ No newline at end of file