From 741374cb694e99ba3b8f0f4e6f78e6199052f025 Mon Sep 17 00:00:00 2001 From: Alexey Yarmosh Date: Fri, 19 Apr 2024 12:10:46 +0200 Subject: [PATCH] feat: update migrations and envs --- .env.development.example | 19 --- .env.example | 3 - .env.production.example | 19 --- .../migrations/20230425A-create-user-role.js | 8 +- .../20230601A-hide-tokens-search.js | 2 +- .../20230913A-add-credits-read-permissions.js | 65 --------- .../20230914A-add-github-webhook-handler.js | 88 ------------ .../20230919A-add-sponsors-cron-handler.js | 88 ------------ ...0230929A-add-adopted-probes-permissions.js | 72 ---------- .../20231006A-set-up-left-panel-buttons.js | 63 -------- .../20231109A-add-user-permissions.js | 1 - ...A-add-adopted-probes-update-permissions.js | 121 ---------------- ...-add-adopted-probes-status-cron-handler.js | 88 ------------ ...add-adopted-probes-credits-cron-handler.js | 88 ------------ ...231217A-update-credits-read-permissions.js | 65 --------- ...-update-adopted-probes-read-permissions.js | 65 --------- ...03A-rename-adopted-probes-github-column.js | 15 -- ...4A-add-user-permissions-to-read-gh-data.js | 68 --------- .../20240105A-migrate-tags-format.js | 33 ----- .../20240121A-copy-data-to-new-collections.js | 75 ---------- .../20240122A-hide-gp-tokens-search.js | 31 ---- ...0240123A-add-user-permissions-gp-tokens.js | 23 --- .../20240131A-add-credits-triggers.js | 66 --------- .../20240201A-add-credits-read-permissions.js | 134 ------------------ .../migrations/20240202A-add-indexes.js | 4 - ...03A-copy-values-to-new-sponsors-columns.js | 18 --- ...0215A-add-user-permissions-to-read-type.js | 66 --------- ...dd-permissions-to-read-adopted-hardware.js | 71 ---------- ...missions-to-read-credits-addition-probe.js | 71 ---------- .../test/api.test.ts | 1 - 30 files changed, 5 insertions(+), 1526 deletions(-) delete mode 100644 src/extensions/migrations/20230913A-add-credits-read-permissions.js delete mode 100644 src/extensions/migrations/20230914A-add-github-webhook-handler.js delete mode 100644 src/extensions/migrations/20230919A-add-sponsors-cron-handler.js delete mode 100644 src/extensions/migrations/20230929A-add-adopted-probes-permissions.js delete mode 100644 src/extensions/migrations/20231006A-set-up-left-panel-buttons.js delete mode 100644 src/extensions/migrations/20231110A-add-adopted-probes-update-permissions.js delete mode 100644 src/extensions/migrations/20231213A-add-adopted-probes-status-cron-handler.js delete mode 100644 src/extensions/migrations/20231214A-add-adopted-probes-credits-cron-handler.js delete mode 100644 src/extensions/migrations/20231217A-update-credits-read-permissions.js delete mode 100644 src/extensions/migrations/20231218A-update-adopted-probes-read-permissions.js delete mode 100644 src/extensions/migrations/20240103A-rename-adopted-probes-github-column.js delete mode 100644 src/extensions/migrations/20240104A-add-user-permissions-to-read-gh-data.js delete mode 100644 src/extensions/migrations/20240105A-migrate-tags-format.js delete mode 100644 src/extensions/migrations/20240121A-copy-data-to-new-collections.js delete mode 100644 src/extensions/migrations/20240122A-hide-gp-tokens-search.js delete mode 100644 src/extensions/migrations/20240123A-add-user-permissions-gp-tokens.js delete mode 100644 src/extensions/migrations/20240131A-add-credits-triggers.js delete mode 100644 src/extensions/migrations/20240201A-add-credits-read-permissions.js delete mode 100644 src/extensions/migrations/20240203A-copy-values-to-new-sponsors-columns.js delete mode 100644 src/extensions/migrations/20240215A-add-user-permissions-to-read-type.js delete mode 100644 src/extensions/migrations/20240221A-add-permissions-to-read-adopted-hardware.js delete mode 100644 src/extensions/migrations/20240222A-add-permissions-to-read-credits-addition-probe.js diff --git a/.env.development.example b/.env.development.example index 45a0df8..efe0469 100644 --- a/.env.development.example +++ b/.env.development.example @@ -36,25 +36,6 @@ AUTH_GITHUB_IDENTIFIER_KEY=id # GitHub API # A classic token (not scoped), required permissions are: read:org, read:user GITHUB_ACCESS_TOKEN= -# Generated during enabling of webhooks and passed to the app, to validate requests -# Create the webhook at https://github.com/sponsors/jsdelivr/dashboard/webhooks/441768912/edit#deliveries -# See WEBHOOK_FLOW_ID in .env.example for the webhook URL -GITHUB_WEBHOOK_SECRET= - -# Globalping API -GLOBALPING_URL=https://api.globalping.io/v1 -GP_SYSTEM_KEY= - -# Geonames API -GEONAMES_USERNAME= - -# App -CREDITS_PER_DOLLAR=2000 -CREDITS_PER_ADOPTED_PROBE_DAY=150 -ADOPTED_PROBES_CHECK_TIME_MAX_DEVIATION_MINS=5 -# To trigger credits assignment probe need to be online >20 hours during the day. Current "Adopted probes status CRON" is "*/10 * * * *", which is 6 times an hour -# So required value is 20 * 6 = 120 -ADOPTED_PROBES_REQUIRED_ONLINE_TIMES=120 # Are updated during `npm run init` AUTH_GITHUB_DEFAULT_ROLE_ID= diff --git a/.env.example b/.env.example index 42f738c..981a28f 100644 --- a/.env.example +++ b/.env.example @@ -5,9 +5,6 @@ DB_DATABASE= DB_USER= DB_PASSWORD= -# ID that will be used for the flow. Any valid UUID. -# The final URL for the webhook is ${host}/flows/trigger/${WEBHOOK_FLOW_ID} -WEBHOOK_FLOW_ID=e8a4c2b2-3ed4-4ddc-b98e-34c1952c2323 DIRECTUS_URL= ADMIN_EMAIL= diff --git a/.env.production.example b/.env.production.example index 65b3072..9249615 100644 --- a/.env.production.example +++ b/.env.production.example @@ -36,25 +36,6 @@ AUTH_GITHUB_IDENTIFIER_KEY=id # GitHub API # A classic token (not scoped), required permissions are: read:org, read:user GITHUB_ACCESS_TOKEN= -# Generated during enabling of webhooks and passed to the app, to validate requests -# Create the webhook at https://github.com/sponsors/jsdelivr/dashboard/webhooks/441768912/edit#deliveries -# See WEBHOOK_FLOW_ID in .env.example for the webhook URL -GITHUB_WEBHOOK_SECRET= - -# Globalping API -GLOBALPING_URL=https://api.globalping.io/v1 -GP_SYSTEM_KEY= - -# Geonames API -GEONAMES_USERNAME= - -# App -CREDITS_PER_DOLLAR=2000 -CREDITS_PER_ADOPTED_PROBE_DAY=150 -ADOPTED_PROBES_CHECK_TIME_MAX_DEVIATION_MINS=5 -# To trigger credits assignment probe need to be online >20 hours during the day. Current "Adopted probes status CRON" is "*/10 * * * *", which is 6 times an hour -# So required value is 20 * 6 = 120 -ADOPTED_PROBES_REQUIRED_ONLINE_TIMES=120 # Are updated during `npm run init` AUTH_GITHUB_DEFAULT_ROLE_ID= diff --git a/src/extensions/migrations/20230425A-create-user-role.js b/src/extensions/migrations/20230425A-create-user-role.js index 4efd4f7..fe9e298 100644 --- a/src/extensions/migrations/20230425A-create-user-role.js +++ b/src/extensions/migrations/20230425A-create-user-role.js @@ -33,7 +33,7 @@ async function createPermissions (roleId) { method: 'POST', body: JSON.stringify([ { - collection: 'tokens', + collection: 'jsd_purge_tokens', action: 'create', role: roleId, permissions: { @@ -44,7 +44,7 @@ async function createPermissions (roleId) { fields: [ 'name', 'value', 'expire', 'origins' ], }, { - collection: 'tokens', + collection: 'jsd_purge_tokens', action: 'read', role: roleId, permissions: { @@ -55,7 +55,7 @@ async function createPermissions (roleId) { fields: [ '*' ], }, { - collection: 'tokens', + collection: 'jsd_purge_tokens', action: 'update', role: roleId, permissions: { @@ -66,7 +66,7 @@ async function createPermissions (roleId) { fields: [ 'name', 'value', 'expire', 'origins' ], }, { - collection: 'tokens', + collection: 'jsd_purge_tokens', action: 'delete', role: roleId, permissions: { diff --git a/src/extensions/migrations/20230601A-hide-tokens-search.js b/src/extensions/migrations/20230601A-hide-tokens-search.js index 73671d1..bb54c18 100644 --- a/src/extensions/migrations/20230601A-hide-tokens-search.js +++ b/src/extensions/migrations/20230601A-hide-tokens-search.js @@ -6,7 +6,7 @@ async function addCssRules () { const response = await fetch(URL, { method: 'PATCH', body: JSON.stringify({ - custom_css: '.search-input {\n display: none !important;\n}\n\nbody:not(:has(.router-link-active[href="/admin/content/tokens"])) .search-input {\n\tdisplay: flex !important;\n}', + custom_css: '.search-input {\n display: none !important;\n}\n\nbody:not(:has(.router-link-active[href="/admin/content/jsd_purge_tokens"])) .search-input {\n\tdisplay: flex !important;\n}', }), headers: { 'Content-Type': 'application/json', diff --git a/src/extensions/migrations/20230913A-add-credits-read-permissions.js b/src/extensions/migrations/20230913A-add-credits-read-permissions.js deleted file mode 100644 index 2e419cf..0000000 --- a/src/extensions/migrations/20230913A-add-credits-read-permissions.js +++ /dev/null @@ -1,65 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function createPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify([ - { - collection: 'credits', - action: 'read', - role: roleId, - permissions: { - _and: [ - { - githubId: { - _eq: '$CURRENT_USER.external_identifier', - }, - }, - ], - }, - fields: [ - 'githubLogin', - 'githubId', - 'credits', - 'comment', - 'date_created', - ], - }, - ]), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - await createPermissions(roleId); - console.log(`Read credits permissions added`); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20230914A-add-github-webhook-handler.js b/src/extensions/migrations/20230914A-add-github-webhook-handler.js deleted file mode 100644 index 8f15ffa..0000000 --- a/src/extensions/migrations/20230914A-add-github-webhook-handler.js +++ /dev/null @@ -1,88 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const WEBHOOK_FLOW_ID = process.env.WEBHOOK_FLOW_ID; - -async function createFlow () { - const URL = `${DIRECTUS_URL}/flows?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - id: WEBHOOK_FLOW_ID, - name: 'Github webhook', - description: 'Add Globalping credits for the Github sponsorship', - status: 'active', - trigger: 'webhook', - accountability: 'all', - options: { - method: 'POST', - }, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function createOperation () { - const URL = `${DIRECTUS_URL}/operations?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - flow: WEBHOOK_FLOW_ID, - name: 'Sponsorship handler', - key: 'sponsorship_handler', - type: 'gh-webhook-handler', - position_x: 19, - position_y: 1, - options: {}, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function assignOperationToFlow (operationId) { - const URL = `${DIRECTUS_URL}/flows/${WEBHOOK_FLOW_ID}?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - operation: operationId, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - await createFlow(); - const operation = await createOperation(); - await assignOperationToFlow(operation.id); - console.log('Github webhook handler added'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20230919A-add-sponsors-cron-handler.js b/src/extensions/migrations/20230919A-add-sponsors-cron-handler.js deleted file mode 100644 index 80d0768..0000000 --- a/src/extensions/migrations/20230919A-add-sponsors-cron-handler.js +++ /dev/null @@ -1,88 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const FLOW_ID = '6847946c-858c-4d8d-a0a1-5a586bb55923'; // Flow id needs to be a uuid, as Directus throws otherwise. This is a random value. - -async function createFlow () { - const URL = `${DIRECTUS_URL}/flows?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - id: FLOW_ID, - name: 'Sponsors CRON', - description: 'Add Globalping credits for recurring sponsorships', - status: 'active', - trigger: 'schedule', - accountability: 'all', - options: { - cron: '0 0 * * *', - }, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function createOperation () { - const URL = `${DIRECTUS_URL}/operations?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - flow: FLOW_ID, - name: 'Sponsors CRON handler', - key: 'sponsorship_cron_handler', - type: 'sponsors-cron-handler', - position_x: 19, - position_y: 1, - options: {}, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function assignOperationToFlow (operationId) { - const URL = `${DIRECTUS_URL}/flows/${FLOW_ID}?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - operation: operationId, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - await createFlow(); - const operation = await createOperation(); - await assignOperationToFlow(operation.id); - console.log('Sponsorship CRON handler added'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20230929A-add-adopted-probes-permissions.js b/src/extensions/migrations/20230929A-add-adopted-probes-permissions.js deleted file mode 100644 index abec9f0..0000000 --- a/src/extensions/migrations/20230929A-add-adopted-probes-permissions.js +++ /dev/null @@ -1,72 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function createPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify([ - { - collection: 'adopted_probes', - action: 'read', - role: roleId, - permissions: { - _and: [ - { - userId: { - _eq: '$CURRENT_USER', - }, - }, - ], - }, - fields: [ - 'date_updated', - 'ip', - 'lastSyncDate', - 'date_created', - 'status', - 'version', - 'country', - 'city', - 'latitude', - 'longitude', - 'asn', - 'network', - ], - }, - ]), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - await createPermissions(roleId); - console.log(`Read credits permissions added`); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20231006A-set-up-left-panel-buttons.js b/src/extensions/migrations/20231006A-set-up-left-panel-buttons.js deleted file mode 100644 index 28c1368..0000000 --- a/src/extensions/migrations/20231006A-set-up-left-panel-buttons.js +++ /dev/null @@ -1,63 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; - -async function addCssRules () { - const URL = `${DIRECTUS_URL}/settings?access_token=${ADMIN_ACCESS_TOKEN}`; - - const result = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - module_bar: [{ - type: 'module', - id: 'content', - enabled: true, - }, - { - type: 'module', - id: 'users', - enabled: true, - }, - { - type: 'module', - id: 'files', - enabled: true, - }, - { - type: 'module', - id: 'insights', - enabled: true, - }, - { - type: 'module', - id: 'settings', - enabled: true, - locked: true, - }, - { - type: 'module', - id: 'probes-adapter', - enabled: true, - }], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - - return result.data; -} - -export async function up () { - await addCssRules(); - console.log('Successfully updated css rules.'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20231109A-add-user-permissions.js b/src/extensions/migrations/20231109A-add-user-permissions.js index 0cb0030..c3b68d9 100644 --- a/src/extensions/migrations/20231109A-add-user-permissions.js +++ b/src/extensions/migrations/20231109A-add-user-permissions.js @@ -45,7 +45,6 @@ async function patchReadPermissions (readPermissions) { 'theme_dark', 'theme_light_overrides', 'theme_dark_overrides', - 'github', ], }), headers: { diff --git a/src/extensions/migrations/20231110A-add-adopted-probes-update-permissions.js b/src/extensions/migrations/20231110A-add-adopted-probes-update-permissions.js deleted file mode 100644 index 2927c27..0000000 --- a/src/extensions/migrations/20231110A-add-adopted-probes-update-permissions.js +++ /dev/null @@ -1,121 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=adopted_probes&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: [ - ...readPermissions.fields, - 'id', - 'name', - 'tags', - ], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function createUpdatePermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify([ - { - collection: 'adopted_probes', - action: 'update', - role: roleId, - permissions: { - _and: [ - { - userId: { - _eq: '$CURRENT_USER', - }, - }, - ], - }, - fields: [ - 'name', - 'tags', - 'city', - ], - }, - { - collection: 'adopted_probes', - action: 'delete', - role: roleId, - permissions: { - _and: [ - { - userId: { - _eq: '$CURRENT_USER', - }, - }, - ], - }, - }, - ]), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - await createUpdatePermissions(roleId); - console.log('Adopted probes update permissions added'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20231213A-add-adopted-probes-status-cron-handler.js b/src/extensions/migrations/20231213A-add-adopted-probes-status-cron-handler.js deleted file mode 100644 index 73eb977..0000000 --- a/src/extensions/migrations/20231213A-add-adopted-probes-status-cron-handler.js +++ /dev/null @@ -1,88 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const FLOW_ID = '284f22f9-0233-44ee-a9e1-503e9a2e3830'; // Flow id needs to be a uuid, as Directus throws otherwise. This is a random value. - -async function createFlow () { - const URL = `${DIRECTUS_URL}/flows?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - id: FLOW_ID, - name: 'Adopted probes status CRON', - description: 'Checks online status of the adopted probes', - status: 'active', - trigger: 'schedule', - accountability: 'all', - options: { - cron: '*/10 * * * *', - }, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function createOperation () { - const URL = `${DIRECTUS_URL}/operations?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - flow: FLOW_ID, - name: 'Adopted probes status CRON handler', - key: 'adopted_probes_status_cron_handler', - type: 'adopted-probes-status-cron-handler', - position_x: 19, - position_y: 1, - options: {}, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function assignOperationToFlow (operationId) { - const URL = `${DIRECTUS_URL}/flows/${FLOW_ID}?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - operation: operationId, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - await createFlow(); - const operation = await createOperation(); - await assignOperationToFlow(operation.id); - console.log('Adopted probes status CRON handler added'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20231214A-add-adopted-probes-credits-cron-handler.js b/src/extensions/migrations/20231214A-add-adopted-probes-credits-cron-handler.js deleted file mode 100644 index 55800b7..0000000 --- a/src/extensions/migrations/20231214A-add-adopted-probes-credits-cron-handler.js +++ /dev/null @@ -1,88 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const FLOW_ID = '4d64c5a9-f731-4654-823d-9bda7f5c4ebe'; // Flow id needs to be a uuid, as Directus throws otherwise. This is a random value. - -async function createFlow () { - const URL = `${DIRECTUS_URL}/flows?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - id: FLOW_ID, - name: 'Adopted probes credits CRON', - description: 'Add Globalping credits for adopted probes', - status: 'active', - trigger: 'schedule', - accountability: 'all', - options: { - cron: '0 0 * * *', - }, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function createOperation () { - const URL = `${DIRECTUS_URL}/operations?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify({ - flow: FLOW_ID, - name: 'Adopted probes credits CRON handler', - key: 'adopted_probes_credits_cron_handler', - type: 'adopted-probes-credits-cron-handler', - position_x: 19, - position_y: 1, - options: {}, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function assignOperationToFlow (operationId) { - const URL = `${DIRECTUS_URL}/flows/${FLOW_ID}?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - operation: operationId, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - await createFlow(); - const operation = await createOperation(); - await assignOperationToFlow(operation.id); - console.log('Adopted probes credits CRON handler added'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20231217A-update-credits-read-permissions.js b/src/extensions/migrations/20231217A-update-credits-read-permissions.js deleted file mode 100644 index c0b53a1..0000000 --- a/src/extensions/migrations/20231217A-update-credits-read-permissions.js +++ /dev/null @@ -1,65 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=credits&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - - const newFields = readPermissions.fields.filter(field => field !== 'githubLogin'); - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: newFields, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log('Credits read permissions updated.'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20231218A-update-adopted-probes-read-permissions.js b/src/extensions/migrations/20231218A-update-adopted-probes-read-permissions.js deleted file mode 100644 index 4b95da5..0000000 --- a/src/extensions/migrations/20231218A-update-adopted-probes-read-permissions.js +++ /dev/null @@ -1,65 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=adopted_probes&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - - const newFields = readPermissions.fields.filter(field => field !== 'date_updated'); - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: newFields, - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log('Credits read permissions updated.'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240103A-rename-adopted-probes-github-column.js b/src/extensions/migrations/20240103A-rename-adopted-probes-github-column.js deleted file mode 100644 index 895ecdf..0000000 --- a/src/extensions/migrations/20240103A-rename-adopted-probes-github-column.js +++ /dev/null @@ -1,15 +0,0 @@ -export async function up (knex) { - const columnExists = await knex.schema.hasColumn('directus_users', 'github'); - - if (!columnExists) { - console.log('"directus_users" table or "github" column doesn\'t exist, rename is not required.'); - return; - } - - await knex.schema.raw('ALTER TABLE `directus_users` RENAME COLUMN `github` TO `github_username`'); - console.log('"github" column successfully renamed'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240104A-add-user-permissions-to-read-gh-data.js b/src/extensions/migrations/20240104A-add-user-permissions-to-read-gh-data.js deleted file mode 100644 index 0c7b401..0000000 --- a/src/extensions/migrations/20240104A-add-user-permissions-to-read-gh-data.js +++ /dev/null @@ -1,68 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=directus_users&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - const filteredFields = readPermissions.fields.filter(field => field !== 'github'); - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: [ - ...filteredFields, - 'github_username', - 'github_organizations', - ], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log('User permissions patched to read new gh fields'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240105A-migrate-tags-format.js b/src/extensions/migrations/20240105A-migrate-tags-format.js deleted file mode 100644 index 6d9019e..0000000 --- a/src/extensions/migrations/20240105A-migrate-tags-format.js +++ /dev/null @@ -1,33 +0,0 @@ -export async function up (knex) { - const probesTableExists = await knex.schema.hasTable('adopted_probes'); - const usersTableExists = await knex.schema.hasTable('directus_users'); - - if (!probesTableExists || !usersTableExists) { - console.log('Required tables do not exist, operation is not required.'); - return; - } - - const rows = await knex('adopted_probes') - .join('directus_users', 'adopted_probes.userId', '=', 'directus_users.id') - .select('adopted_probes.id', 'adopted_probes.tags', 'directus_users.github_username'); - - for (let row of rows) { - if (row.tags) { - try { - let tags = JSON.parse(row.tags); - let updatedTags = tags.map(tag => typeof tag === 'string' ? { prefix: row.github_username, value: tag } : tag); - await knex('adopted_probes') - .where({ id: row.id }) - .update({ tags: JSON.stringify(updatedTags) }); - } catch (err) { - console.error(`Error parsing JSON for row id ${row.id}:`, err); - } - } - } - - console.log('Completed migrating "tags" column in "adopted_probes" table'); -} - -export async function down () { - console.log('There is no down operation for this migration.'); -} diff --git a/src/extensions/migrations/20240121A-copy-data-to-new-collections.js b/src/extensions/migrations/20240121A-copy-data-to-new-collections.js deleted file mode 100644 index dec3e14..0000000 --- a/src/extensions/migrations/20240121A-copy-data-to-new-collections.js +++ /dev/null @@ -1,75 +0,0 @@ -export async function up (knex) { - const tokensTableExists = await knex.schema.hasTable('tokens'); - const probesTableExists = await knex.schema.hasTable('adopted_probes'); - const usersTableExists = await knex.schema.hasTable('directus_users'); - - await knex.transaction(async (trx) => { - if (!tokensTableExists || !probesTableExists || !usersTableExists) { - console.log('Old collections do not exist, migration of data is not required.'); - } else { - await trx.raw(`INSERT INTO jsd_purge_tokens ( - date_created, - date_updated, - expire, - id, - name, - origins, - user_created, - user_updated, - value - ) SELECT date_created, date_updated, expire, id, name, origins, user_created, user_updated, value FROM tokens`); - - await trx.raw(`INSERT INTO gp_adopted_probes ( - asn, - country, - city, - countryOfCustomCity, - date_created, - date_updated, - id, - ip, - isCustomCity, - lastSyncDate, - latitude, - longitude, - name, - network, - onlineTimesToday, - state, - status, - tags, - userId, - uuid, - version - ) SELECT asn, country, city, countryOfCustomCity, date_created, date_updated, id, ip, isCustomCity, lastSyncDate, latitude, longitude, name, network, onlineTimesToday, state, status, tags, userId, uuid, version FROM adopted_probes`); - - await trx.raw(`INSERT INTO gp_credits ( - comment, - credits, - date_created, - date_updated, - githubId, - id, - user_updated - ) SELECT comment, credits, date_created, date_updated, githubId, id, user_updated FROM credits`); - } - - await trx('directus_permissions').where('collection', 'tokens').update({ - collection: 'jsd_purge_tokens', - }); - - await trx('directus_permissions').where('collection', 'adopted_probes').update({ - collection: 'gp_adopted_probes', - }); - - await trx('directus_permissions').where('collection', 'credits').update({ - collection: 'gp_credits', - }); - }); - - console.log('Completed migration to new collections'); -} - -export async function down () { - console.log('There is no down operation for this migration.'); -} diff --git a/src/extensions/migrations/20240122A-hide-gp-tokens-search.js b/src/extensions/migrations/20240122A-hide-gp-tokens-search.js deleted file mode 100644 index 06704a5..0000000 --- a/src/extensions/migrations/20240122A-hide-gp-tokens-search.js +++ /dev/null @@ -1,31 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; - -async function addCssRules () { - const URL = `${DIRECTUS_URL}/settings?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - custom_css: 'body:has(.router-link-active[href="/admin/content/jsd_purge_tokens"]) .search-input {\n\tdisplay: none !important;\n}\n\nbody:has(.router-link-active[href="/admin/content/gp_tokens"]) .search-input {\n\tdisplay: none !important;\n}', - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - await addCssRules(); - console.log('Successfully updated css rules.'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240123A-add-user-permissions-gp-tokens.js b/src/extensions/migrations/20240123A-add-user-permissions-gp-tokens.js deleted file mode 100644 index 2e1390a..0000000 --- a/src/extensions/migrations/20240123A-add-user-permissions-gp-tokens.js +++ /dev/null @@ -1,23 +0,0 @@ -export async function up (knex) { - const rowsToCopy = await knex.select('role', 'action', 'permissions', 'fields') - .from('directus_permissions') - .where('collection', 'jsd_purge_tokens'); - - const newRows = rowsToCopy.map((row) => { - return { - role: row.role, - action: row.action, - permissions: row.permissions, - fields: row.fields, - collection: 'gp_tokens', - }; - }); - - await knex('directus_permissions').insert(newRows); - - console.log('Added gp_tokens collection permissions'); -} - -export async function down () { - console.log('There is no down operation for this migration.'); -} diff --git a/src/extensions/migrations/20240131A-add-credits-triggers.js b/src/extensions/migrations/20240131A-add-credits-triggers.js deleted file mode 100644 index e45cca1..0000000 --- a/src/extensions/migrations/20240131A-add-credits-triggers.js +++ /dev/null @@ -1,66 +0,0 @@ -export async function up (knex) { - await knex.raw(` - CREATE TRIGGER after_gp_credits_additions_insert - BEFORE INSERT ON gp_credits_additions - FOR EACH ROW - BEGIN - DECLARE found_user_id CHAR(36); - SELECT id INTO found_user_id FROM directus_users WHERE external_identifier = NEW.github_id LIMIT 1; - - IF found_user_id IS NOT NULL THEN - INSERT INTO gp_credits (user_id, amount) - VALUES (found_user_id, NEW.amount) - ON DUPLICATE KEY UPDATE - gp_credits.amount = COALESCE(gp_credits.amount, 0) + NEW.amount; - ELSE - SET NEW.consumed = FALSE; - END IF; - END; - `); - - await knex.raw(` - ALTER TABLE gp_credits - ADD CONSTRAINT gp_credits_amount_positive CHECK (amount >= 0); - `); - - await knex.raw(` - ALTER TABLE gp_credits_additions - ADD CONSTRAINT gp_credits_additions_amount_positive CHECK (amount >= 0); - `); - - await knex.raw(` - ALTER TABLE gp_credits_deductions - ADD CONSTRAINT gp_credits_deductions_amount_positive CHECK (amount >= 0); - `); - - await knex.raw(` - ALTER TABLE gp_credits_deductions - ADD CONSTRAINT unique_user_id_date UNIQUE (user_id, date); - `); - - await knex.raw(` - CREATE TRIGGER after_gp_credits_update - AFTER UPDATE ON gp_credits - FOR EACH ROW - BEGIN - IF NEW.amount < OLD.amount THEN - UPDATE gp_credits_deductions - SET amount = amount + (OLD.amount - NEW.amount) - WHERE user_id = NEW.user_id AND date = CURRENT_DATE; - - IF ROW_COUNT() = 0 THEN - INSERT INTO gp_credits_deductions (user_id, amount, date) - VALUES (NEW.user_id, OLD.amount - NEW.amount, CURRENT_DATE) - ON DUPLICATE KEY UPDATE - amount = amount + (OLD.amount - NEW.amount); - END IF; - END IF; - END; - `); - - console.log('Triggers for gp_credits_additions and gp_credits created'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240201A-add-credits-read-permissions.js b/src/extensions/migrations/20240201A-add-credits-read-permissions.js deleted file mode 100644 index 05e754a..0000000 --- a/src/extensions/migrations/20240201A-add-credits-read-permissions.js +++ /dev/null @@ -1,134 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function createPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL, { - method: 'POST', - body: JSON.stringify([ - { - collection: 'gp_credits_additions', - action: 'read', - role: roleId, - permissions: { - _and: [ - { - github_id: { - _eq: '$CURRENT_USER.external_identifier', - }, - }, - ], - }, - fields: [ - 'amount', - 'comment', - 'date_created', - 'user_updated', - ], - }, - { - collection: 'gp_credits_deductions', - action: 'read', - role: roleId, - permissions: { - _and: [ - { - user_id: { - _eq: '$CURRENT_USER', - }, - }, - ], - }, - fields: [ - 'date', - 'amount', - 'date_created', - 'date_updated', - ], - }, - ]), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=gp_credits&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - permissions: { - _and: [ - { - user_id: { - _eq: '$CURRENT_USER', - }, - }, - ], - }, - fields: [ - 'amount', - ], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - await createPermissions(roleId); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log(`Read credits permissions added`); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240202A-add-indexes.js b/src/extensions/migrations/20240202A-add-indexes.js index b65ccd5..49ab0d6 100644 --- a/src/extensions/migrations/20240202A-add-indexes.js +++ b/src/extensions/migrations/20240202A-add-indexes.js @@ -1,9 +1,5 @@ export async function up (knex) { await knex.raw(`ALTER TABLE jsd_purge_tokens ADD INDEX value_index (value);`); - await knex.raw(`ALTER TABLE gp_tokens ADD INDEX value_index (value);`); - await knex.raw(`ALTER TABLE gp_adopted_probes ADD INDEX ip_index (ip);`); - await knex.raw(`ALTER TABLE gp_credits ADD INDEX user_id_index (user_id);`); - await knex.raw(`ALTER TABLE gp_credits_deductions ADD INDEX user_id_and_date_index (user_id, date);`); console.log('Indexes added'); } diff --git a/src/extensions/migrations/20240203A-copy-values-to-new-sponsors-columns.js b/src/extensions/migrations/20240203A-copy-values-to-new-sponsors-columns.js deleted file mode 100644 index 6939429..0000000 --- a/src/extensions/migrations/20240203A-copy-values-to-new-sponsors-columns.js +++ /dev/null @@ -1,18 +0,0 @@ -export async function up (knex) { - const oldFormatColumns = await knex.schema.hasColumn('sponsors', 'githubId'); - - if (oldFormatColumns) { - await knex('sponsors').update({ - github_id: knex.ref('githubId'), - github_login: knex.ref('githubLogin'), - monthly_amount: knex.ref('monthlyAmount'), - last_earning_date: knex.ref('lastEarningDate'), - }); - } - - console.log('Sponsors values copied'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240215A-add-user-permissions-to-read-type.js b/src/extensions/migrations/20240215A-add-user-permissions-to-read-type.js deleted file mode 100644 index 59e97bf..0000000 --- a/src/extensions/migrations/20240215A-add-user-permissions-to-read-type.js +++ /dev/null @@ -1,66 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=directus_users&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: [ - ...readPermissions.fields, - 'user_type', - ], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log('User permissions patched to read user type'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240221A-add-permissions-to-read-adopted-hardware.js b/src/extensions/migrations/20240221A-add-permissions-to-read-adopted-hardware.js deleted file mode 100644 index 3cf447f..0000000 --- a/src/extensions/migrations/20240221A-add-permissions-to-read-adopted-hardware.js +++ /dev/null @@ -1,71 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -const COLLECTION_NAME = 'gp_adopted_probes'; -const FIELDS_TO_REMOVE = []; -const FIELDS_TO_ADD = [ 'hardwareDevice' ]; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=${COLLECTION_NAME}&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - const filteredFields = readPermissions.fields.filter(field => !FIELDS_TO_REMOVE.includes(field)); - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: [ - ...filteredFields, - ...FIELDS_TO_ADD, - ], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log('User permissions patched read adopted probes "hardwareDevice" field'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/migrations/20240222A-add-permissions-to-read-credits-addition-probe.js b/src/extensions/migrations/20240222A-add-permissions-to-read-credits-addition-probe.js deleted file mode 100644 index dd6c58a..0000000 --- a/src/extensions/migrations/20240222A-add-permissions-to-read-credits-addition-probe.js +++ /dev/null @@ -1,71 +0,0 @@ -const DIRECTUS_URL = process.env.DIRECTUS_URL; -const ADMIN_ACCESS_TOKEN = process.env.ADMIN_ACCESS_TOKEN; -const USER_ROLE_NAME = 'User'; - -const COLLECTION_NAME = 'gp_credits_additions'; -const FIELDS_TO_REMOVE = []; -const FIELDS_TO_ADD = [ 'adopted_probe' ]; - -async function getUserRoleId () { - const URL = `${DIRECTUS_URL}/roles?filter[name][_eq]=${USER_ROLE_NAME}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data[0].id; -} - -async function getUserPermissions (roleId) { - const URL = `${DIRECTUS_URL}/permissions?filter[collection][_eq]=${COLLECTION_NAME}&filter[role][_eq]=${roleId}&access_token=${ADMIN_ACCESS_TOKEN}`; - const response = await fetch(URL).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - const permissions = response.data; - const readPermissions = permissions.find(({ action }) => action === 'read'); - - return { readPermissions }; -} - -async function patchReadPermissions (readPermissions) { - const URL = `${DIRECTUS_URL}/permissions/${readPermissions.id}?access_token=${ADMIN_ACCESS_TOKEN}`; - const filteredFields = readPermissions.fields.filter(field => !FIELDS_TO_REMOVE.includes(field)); - - const response = await fetch(URL, { - method: 'PATCH', - body: JSON.stringify({ - ...readPermissions, - fields: [ - ...filteredFields, - ...FIELDS_TO_ADD, - ], - }), - headers: { - 'Content-Type': 'application/json', - }, - }).then((response) => { - if (!response.ok) { - throw new Error(`Fetch request failed. Status: ${response.status}`); - } - - return response.json(); - }); - return response.data; -} - -export async function up () { - const roleId = await getUserRoleId(); - const { readPermissions } = await getUserPermissions(roleId); - await patchReadPermissions(readPermissions); - console.log('User permissions patched to read credits additions "adopted_probe" field'); -} - -export async function down () { - console.log('There is no down operation for that migration.'); -} diff --git a/src/extensions/operations/remove-banned-users-cron-handler/test/api.test.ts b/src/extensions/operations/remove-banned-users-cron-handler/test/api.test.ts index ae5658e..f5a31c5 100644 --- a/src/extensions/operations/remove-banned-users-cron-handler/test/api.test.ts +++ b/src/extensions/operations/remove-banned-users-cron-handler/test/api.test.ts @@ -12,7 +12,6 @@ describe('Remove banned users CRON handler', () => { const getSchema = (() => Promise.resolve({})) as OperationContext['getSchema']; const env = { GITHUB_WEBHOOK_SECRET: '77a9a254554d458f5025bb38ad1648a3bb5795e8', - CREDITS_PER_DOLLAR: '10000', }; const readByQuery = sinon.stub();