Skip to content

Commit 6f3d6d5

Browse files
authored
Merge pull request omnivore-app#3755 from omnivore-app/fix/email-sign-up
fix/email sign up
2 parents bfc1be6 + 200354d commit 6f3d6d5

File tree

6 files changed

+166
-17
lines changed

6 files changed

+166
-17
lines changed

packages/api/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@
7878
"image-size": "^1.0.2",
7979
"intercom-client": "^3.1.4",
8080
"ioredis": "^5.3.2",
81-
"redis": "^4.6.13",
8281
"jsonwebtoken": "^8.5.1",
8382
"jwks-rsa": "^2.0.3",
8483
"langchain": "^0.1.21",
@@ -95,6 +94,7 @@
9594
"posthog-node": "^3.6.3",
9695
"private-ip": "^2.3.3",
9796
"prom-client": "^15.1.0",
97+
"redis": "^4.6.13",
9898
"rss-parser": "^3.13.0",
9999
"sanitize-html": "^2.3.2",
100100
"sax": "^1.3.0",
@@ -106,6 +106,7 @@
106106
"typeorm": "^0.3.4",
107107
"typeorm-naming-strategies": "^4.1.0",
108108
"underscore": "^1.13.6",
109+
"url-pattern": "^1.0.3",
109110
"urlsafe-base64": "^1.0.0",
110111
"uuid": "^8.3.1",
111112
"voca": "^1.4.0",
@@ -167,4 +168,4 @@
167168
"volta": {
168169
"extends": "../../package.json"
169170
}
170-
}
171+
}

packages/api/src/jobs/process-youtube-video.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { enqueueProcessYouTubeTranscript } from '../utils/createTask'
1414
import { stringToHash } from '../utils/helpers'
1515
import { logger } from '../utils/logger'
1616
import { parsePreparedContent } from '../utils/parser'
17+
import { videoIdFromYouTubeUrl } from '../utils/youtube'
1718

1819
export interface ProcessYouTubeVideoJobData {
1920
userId: string
@@ -334,7 +335,7 @@ export const processYouTubeVideo = async (
334335
}
335336

336337
videoURL = new URL(libraryItem.originalUrl)
337-
const videoId = videoURL.searchParams.get('v')
338+
const videoId = videoIdFromYouTubeUrl(libraryItem.originalUrl)
338339

339340
if (!videoId) {
340341
logger.warning('no video id for supplied youtube url', {

packages/api/src/pubsub.ts

+3-14
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,12 @@ import {
1010
enqueueWebhookJob,
1111
} from './utils/createTask'
1212
import { buildLogger } from './utils/logger'
13+
import { isYouTubeVideoURL } from './utils/youtube'
1314

1415
const logger = buildLogger('pubsub')
1516

1617
const client = new PubSub()
1718

18-
const isYouTubeVideoURL = (url: string | undefined): boolean => {
19-
if (!url) {
20-
return false
21-
}
22-
const u = new URL(url)
23-
if (!u.host.endsWith('youtube.com') && !u.host.endsWith('youtu.be')) {
24-
return false
25-
}
26-
const videoId = u.searchParams.get('v')
27-
return videoId != null
28-
}
29-
3019
export const createPubSubClient = (): PubsubClient => {
3120
const publish = (topicName: string, msg: Buffer): Promise<void> => {
3221
if (env.dev.isLocal) {
@@ -93,11 +82,11 @@ export const createPubSubClient = (): PubsubClient => {
9382
// })
9483
// }
9584

96-
const isYoutubeVideo = (data: any): data is { originalUrl: string } => {
85+
const isItemWithURL = (data: any): data is { originalUrl: string } => {
9786
return 'originalUrl' in data
9887
}
9988

100-
if (isYoutubeVideo(data) && isYouTubeVideoURL(data['originalUrl'])) {
89+
if (isItemWithURL(data) && isYouTubeVideoURL(data['originalUrl'])) {
10190
await enqueueProcessYouTubeVideo({
10291
userId,
10392
libraryItemId,

packages/api/src/routers/auth/auth_router.ts

+11
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,17 @@ export function authRouter() {
500500
)
501501
}
502502
const { email, password, name, username, bio, pictureUrl } = req.body
503+
504+
function isURLPresent(input: string): boolean {
505+
const urlRegex = /(https?:\/\/[^\s]+)/g
506+
return urlRegex.test(input)
507+
}
508+
509+
if (isURLPresent(email) || isURLPresent(name) || isURLPresent(username)) {
510+
res.redirect(`${env.client.url}/auth/email-signup?errorCodes=UNKNOWN`)
511+
return
512+
}
513+
503514
// trim whitespace in email address
504515
const trimmedEmail = email.trim()
505516
try {

packages/api/src/utils/youtube.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import UrlPattern from 'url-pattern'
2+
3+
export const videoIdFromYouTubeUrl = (
4+
urlString: string | undefined
5+
): string | undefined => {
6+
if (!urlString) {
7+
return undefined
8+
}
9+
10+
const url = new URL(urlString)
11+
if (
12+
!url.hostname.endsWith('youtube.com') &&
13+
!url.hostname.endsWith('youtu.be')
14+
) {
15+
return undefined
16+
}
17+
18+
const videoId = url.searchParams.get('v')
19+
if (videoId) {
20+
return videoId || undefined
21+
}
22+
23+
const parsed = (() => {
24+
const parsedUrl = new URL(url)
25+
parsedUrl.search = ''
26+
return parsedUrl.toString()
27+
})()
28+
29+
const shortVideo = new UrlPattern('http(s)\\://(www.)youtu.be/:videoId')
30+
const directVideo = new UrlPattern(
31+
'(http(s)\\://)(www.)youtube.com/v/:videoId'
32+
)
33+
const embedVideo = new UrlPattern(
34+
'(http(s)\\://)(www.)youtube.com/embed/:videoId'
35+
)
36+
37+
let params = shortVideo.match(parsed) as Record<string, string>
38+
if (params && params.videoId) {
39+
return params.videoId
40+
}
41+
42+
params = directVideo.match(parsed) as Record<string, string>
43+
if (params && params.videoId) {
44+
return params.videoId
45+
}
46+
47+
params = embedVideo.match(parsed) as Record<string, string>
48+
if (params && params.videoId) {
49+
return params.videoId
50+
}
51+
52+
return undefined
53+
}
54+
55+
export const isYouTubeVideoURL = (url: string | undefined): boolean => {
56+
if (!url) {
57+
return false
58+
}
59+
const videoId = videoIdFromYouTubeUrl(url)
60+
return videoId != null
61+
}
+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import 'mocha'
2+
import { expect } from 'chai'
3+
import {
4+
isYouTubeVideoURL,
5+
videoIdFromYouTubeUrl,
6+
} from '../../src/utils/youtube'
7+
8+
describe('videoIdFromYouTubeUrl', () => {
9+
it('Returns video id for video with playlist id', () => {
10+
const result = videoIdFromYouTubeUrl(
11+
'https://www.youtube.com/watch?v=kfchvCyHmsc&list=PLDyKn8uKYtRalFdBWtv_EjDtUo2UEbu-a'
12+
)
13+
expect(result).to.eq('kfchvCyHmsc')
14+
})
15+
16+
it('Returns video id for direct url', () => {
17+
const result = videoIdFromYouTubeUrl(
18+
'https://www.youtube.com/v/vLfAtCbE_Jc'
19+
)
20+
expect(result).to.eq('vLfAtCbE_Jc')
21+
})
22+
23+
it('Returns video id for standard url', () => {
24+
const result = videoIdFromYouTubeUrl(
25+
'https://www.youtube.com/watch?v=vLfAtCbE_Jc'
26+
)
27+
expect(result).to.eq('vLfAtCbE_Jc')
28+
})
29+
30+
it('Returns video id for short url', () => {
31+
const result = videoIdFromYouTubeUrl('https://youtu.be/vLfAtCbE_Jc')
32+
expect(result).to.eq('vLfAtCbE_Jc')
33+
})
34+
35+
it('Returns video id for short url with share id', () => {
36+
const result = videoIdFromYouTubeUrl(
37+
'https://youtu.be/iZxR7rPdvuQ?si=ad73DTmmXL_lbn31'
38+
)
39+
expect(result).to.eq('iZxR7rPdvuQ')
40+
})
41+
42+
it('Returns video id for embed url', () => {
43+
const result = videoIdFromYouTubeUrl(
44+
'https://www.youtube.com/embed/vLfAtCbE_Jc'
45+
)
46+
expect(result).to.eq('vLfAtCbE_Jc')
47+
})
48+
49+
it('Returns undefined for non-youtube url', () => {
50+
const result = videoIdFromYouTubeUrl(
51+
'https://omnivore.app/iZxR7rPdvuQ?si=ad73DTmmXL_lbn31'
52+
)
53+
expect(result).to.eq(undefined)
54+
})
55+
56+
it('Returns undefined for non-youtube short url', () => {
57+
const result = videoIdFromYouTubeUrl('https://omnivore.app/?v=iZxR7rPdvuQ')
58+
expect(result).to.eq(undefined)
59+
})
60+
61+
it('Returns video id when port is added', () => {
62+
const result = videoIdFromYouTubeUrl(
63+
'https://www.youtube.com:443/watch?v=kfchvCyHmsc'
64+
)
65+
expect(result).to.eq('kfchvCyHmsc')
66+
})
67+
})
68+
69+
describe('isYouTubeVideoURL', () => {
70+
it('Returns false for a shorts URL', () => {
71+
const result = isYouTubeVideoURL(
72+
'https://www.youtube.com/shorts/ZsQKYwXbo4s'
73+
)
74+
expect(result).to.eq(false)
75+
})
76+
it('Returns false for a non-youtube URL', () => {
77+
const result = isYouTubeVideoURL('https://omnivore.app/about')
78+
expect(result).to.eq(false)
79+
})
80+
it('Returns true for a video URL', () => {
81+
const result = isYouTubeVideoURL(
82+
'https://www.youtube.com/watch?v=p4YOXmm839c'
83+
)
84+
expect(result).to.eq(true)
85+
})
86+
})

0 commit comments

Comments
 (0)