-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP WIP # Conflicts: # packages/worker/package.json # packages/worker/workers/bookmark-initializer/index.js Deps WIP Refactor PgClient types WIP
- Loading branch information
Showing
43 changed files
with
579 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* Normalizes a URL object by modifying its host property if necessary. | ||
* | ||
* @param {string} url - The URL string to be normalized. | ||
* @returns {Promise<URL>} An object containing the normalized URL string. | ||
*/ | ||
export async function normalizeURL (url) { | ||
const urlObj = new URL(url) | ||
if (urlObj.host === 'm.youtube.com') urlObj.host = 'www.youtube.com' | ||
return urlObj | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/** | ||
* @import { PgClient } from '@breadcrum/resources/types/pg-client.js' | ||
*/ | ||
|
||
import SQL from '@nearform/sql' | ||
import { getOrCreateDefaultFeed } from '../feeds/default-feed-query.js' | ||
|
||
/** | ||
* Creates an episode entry in the database. | ||
* | ||
* This function first retrieves or creates a default feed for the given user. Then, it inserts a new episode | ||
* into the `episodes` table with the provided details and returns the newly created episode object. | ||
* | ||
* @param {object} params - The parameters for creating an episode. | ||
* @param {PgClient} params.client - The database client for executing queries, an instance of a pg connection from `fastify.pg` or `node-pg`. | ||
* @param {string} params.userId - The ID of the user who owns the episode. | ||
* @param {string} params.bookmarkId - The ID of the bookmark associated with the episode. | ||
* @param {string} params.type - The type of the episode. | ||
* @param {string} params.medium - The medium of the episode (e.g., audio, video). | ||
* @param {string} params.url - The URL of the episode. | ||
* @returns {Promise<{ | ||
* id: string, | ||
* type: string, | ||
* medium: string, | ||
* podcast_feed_id: string, | ||
* url: string | ||
* }>} A promise that resolves to the newly created episode object, including its ID, type, medium, podcast feed ID, and URL. | ||
*/ | ||
export async function createEpisode ({ | ||
client, | ||
userId, | ||
bookmarkId, | ||
type, | ||
medium, | ||
url, | ||
}) { | ||
const defaultFeedId = await getOrCreateDefaultFeed({ client, userId }) | ||
|
||
const createEpisodeQuery = SQL` | ||
INSERT INTO episodes (owner_id, podcast_feed_id, bookmark_id, type, medium, url) | ||
VALUES (${userId}, ${defaultFeedId}, ${bookmarkId}, ${type}, ${medium}, ${url}) | ||
returning id, type, medium, podcast_feed_id, url; | ||
` | ||
|
||
const episodeResults = await client.query(createEpisodeQuery) | ||
const episode = episodeResults.rows[0] | ||
return episode | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* eslint-disable camelcase */ | ||
|
||
/** | ||
* @import { PgClient } from '@breadcrum/resources/types/pg-client.js' | ||
*/ | ||
|
||
import SQL from '@nearform/sql' | ||
|
||
/** | ||
* Retrieves or creates a default podcast feed for a given user. | ||
* | ||
* This function first attempts to retrieve the user's default podcast feed ID from the database. | ||
* If the user does not have a default podcast feed, the function creates a new podcast feed, | ||
* assigns it as the user's default, and returns the new feed's ID. | ||
* | ||
* The process of creating a new feed and updating the user's default feed ID is performed | ||
* within a database transaction to ensure data consistency. | ||
* | ||
* @param {Object} params - The function parameters. | ||
* @param {PgClient} params.client - The database client for executing queries, an instance of a pg connection from `fastify.pg` or `node-pg`. | ||
* @param {string} params.userId - The ID of the user for whom to retrieve or create the default podcast feed. | ||
* @returns {Promise<string>} The ID of the default podcast feed for the given user. | ||
* @throws {Error} Throws an error if the database transaction fails. | ||
*/ | ||
export async function getOrCreateDefaultFeed ({ | ||
client, | ||
userId, | ||
}) { | ||
const getDefaultFeed = SQL` | ||
SELECT default_podcast_feed_id | ||
FROM users | ||
WHERE id = ${userId}; | ||
` | ||
|
||
const defaultFeedResults = await client.query(getDefaultFeed) | ||
let { default_podcast_feed_id } = defaultFeedResults.rows[0] | ||
|
||
if (!default_podcast_feed_id) { | ||
try { | ||
await client.query(SQL`BEGIN`) | ||
const createDefaultFeed = SQL` | ||
INSERT INTO podcast_feeds (owner_id) | ||
VALUES (${userId}) | ||
returning id; | ||
` | ||
|
||
const defaultFeedResults = await client.query(createDefaultFeed) | ||
|
||
default_podcast_feed_id = defaultFeedResults.rows[0].id | ||
|
||
const applyDefaultFeed = SQL` | ||
update users | ||
set default_podcast_feed_id = ${default_podcast_feed_id} | ||
where id = ${userId}; | ||
` | ||
|
||
await client.query(applyDefaultFeed) | ||
await client.query(SQL`COMMIT`) | ||
} catch (err) { | ||
await client.query(SQL`ROLLBACK`) | ||
throw err | ||
} | ||
} | ||
|
||
return default_podcast_feed_id | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { PoolClient } from 'pg' | ||
import { PostgresDb } from '@fastify/postgres' | ||
|
||
export type PgClient = PoolClient | PostgresDb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* @param {Url} url A URL object to check | ||
* @return {[type]} [description] | ||
*/ | ||
export async function ssrfCheck (url) { | ||
try { | ||
// Validate protocol | ||
if (url.protocol !== 'https:' && url.protocol !== 'http:') { | ||
return { | ||
ssrf: false | ||
} | ||
} | ||
|
||
// Block cloud metadata endpoints | ||
const blockedHostnames = ['169.254.169.254', 'metadata.google.internal'] | ||
if (blockedHostnames.includes(url.hostname)) { | ||
return false // Block specific metadata endpoints | ||
} | ||
|
||
// Resolve hostname to IP addresses | ||
const addresses = await dns.lookup(url.hostname, { all: true }) | ||
|
||
// Validate each resolved IP | ||
for (const { address } of addresses) { | ||
if (isBlockedIP(address)) { | ||
return false // Blocked IP detected | ||
} | ||
} | ||
|
||
// Additional DNS rebinding check | ||
await dnsRebindingCheck(url.hostname) | ||
|
||
return true // Passed all checks, URL is safe | ||
} catch (err) { | ||
console.error('Error validating URL:', err.message) | ||
return false // Fail closed on error | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
alter table bookmarks | ||
add column original_url text; | ||
|
||
comment on column bookmarks.original_url is 'The original, unnormalized URL of the bookmark.'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
alter table bookmarks | ||
drop column if exists original_url; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.