diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-03 17:33:44 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-03 18:03:36 +0200 |
commit | 10363c74c1d869f0e0c7bc4d0367b1f34d1bb6a4 (patch) | |
tree | 008f8dad8032684f46105a261b27b2d6f05b36eb /server/lib | |
parent | 5e08989ede1a340b9edb94465a11b1e04bf24094 (diff) | |
download | PeerTube-10363c74c1d869f0e0c7bc4d0367b1f34d1bb6a4.tar.gz PeerTube-10363c74c1d869f0e0c7bc4d0367b1f34d1bb6a4.tar.zst PeerTube-10363c74c1d869f0e0c7bc4d0367b1f34d1bb6a4.zip |
Move middleware utils in middlewares
helpers modules should not import models
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/actors/get.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/actors/index.ts | 1 | ||||
-rw-r--r-- | server/lib/activitypub/actors/refresh.ts | 4 | ||||
-rw-r--r-- | server/lib/activitypub/actors/shared/index.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/actors/webfinger.ts | 67 | ||||
-rw-r--r-- | server/lib/activitypub/videos/get.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/videos/refresh.ts | 2 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-follow.ts | 3 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-refresher.ts | 2 | ||||
-rw-r--r-- | server/lib/model-loaders/actor.ts | 16 | ||||
-rw-r--r-- | server/lib/model-loaders/index.ts | 2 | ||||
-rw-r--r-- | server/lib/model-loaders/video.ts | 64 | ||||
-rw-r--r-- | server/lib/server-config-manager.ts | 2 | ||||
-rw-r--r-- | server/lib/signup.ts | 62 |
14 files changed, 221 insertions, 10 deletions
diff --git a/server/lib/activitypub/actors/get.ts b/server/lib/activitypub/actors/get.ts index 0d5bea789..e7e87a967 100644 --- a/server/lib/activitypub/actors/get.ts +++ b/server/lib/activitypub/actors/get.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | 1 | ||
2 | import { checkUrlsSameHost, getAPId } from '@server/helpers/activitypub' | 2 | import { checkUrlsSameHost, getAPId } from '@server/helpers/activitypub' |
3 | import { ActorFetchByUrlType, fetchActorByUrl } from '@server/helpers/actor' | ||
4 | import { retryTransactionWrapper } from '@server/helpers/database-utils' | 3 | import { retryTransactionWrapper } from '@server/helpers/database-utils' |
5 | import { logger } from '@server/helpers/logger' | 4 | import { logger } from '@server/helpers/logger' |
6 | import { JobQueue } from '@server/lib/job-queue' | 5 | import { JobQueue } from '@server/lib/job-queue' |
6 | import { ActorFetchByUrlType, fetchActorByUrl } from '@server/lib/model-loaders' | ||
7 | import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models' | 7 | import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models' |
8 | import { ActivityPubActor } from '@shared/models' | 8 | import { ActivityPubActor } from '@shared/models' |
9 | import { refreshActorIfNeeded } from './refresh' | 9 | import { refreshActorIfNeeded } from './refresh' |
diff --git a/server/lib/activitypub/actors/index.ts b/server/lib/activitypub/actors/index.ts index a54da6798..5ee2a6f1a 100644 --- a/server/lib/activitypub/actors/index.ts +++ b/server/lib/activitypub/actors/index.ts | |||
@@ -3,3 +3,4 @@ export * from './image' | |||
3 | export * from './keys' | 3 | export * from './keys' |
4 | export * from './refresh' | 4 | export * from './refresh' |
5 | export * from './updater' | 5 | export * from './updater' |
6 | export * from './webfinger' | ||
diff --git a/server/lib/activitypub/actors/refresh.ts b/server/lib/activitypub/actors/refresh.ts index ff3b249d0..9f2289bfa 100644 --- a/server/lib/activitypub/actors/refresh.ts +++ b/server/lib/activitypub/actors/refresh.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import { ActorFetchByUrlType } from '@server/helpers/actor' | ||
2 | import { logger } from '@server/helpers/logger' | 1 | import { logger } from '@server/helpers/logger' |
3 | import { PeerTubeRequestError } from '@server/helpers/requests' | 2 | import { PeerTubeRequestError } from '@server/helpers/requests' |
4 | import { getUrlFromWebfinger } from '@server/helpers/webfinger' | 3 | import { ActorFetchByUrlType } from '@server/lib/model-loaders' |
5 | import { ActorModel } from '@server/models/actor/actor' | 4 | import { ActorModel } from '@server/models/actor/actor' |
6 | import { MActorAccountChannelId, MActorFull } from '@server/types/models' | 5 | import { MActorAccountChannelId, MActorFull } from '@server/types/models' |
7 | import { HttpStatusCode } from '@shared/core-utils' | 6 | import { HttpStatusCode } from '@shared/core-utils' |
8 | import { fetchRemoteActor } from './shared' | 7 | import { fetchRemoteActor } from './shared' |
9 | import { APActorUpdater } from './updater' | 8 | import { APActorUpdater } from './updater' |
9 | import { getUrlFromWebfinger } from './webfinger' | ||
10 | 10 | ||
11 | async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannelId> ( | 11 | async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannelId> ( |
12 | actorArg: T, | 12 | actorArg: T, |
diff --git a/server/lib/activitypub/actors/shared/index.ts b/server/lib/activitypub/actors/shared/index.ts index a2ff468cf..52af1a8e1 100644 --- a/server/lib/activitypub/actors/shared/index.ts +++ b/server/lib/activitypub/actors/shared/index.ts | |||
@@ -1,3 +1,3 @@ | |||
1 | export * from './creator' | 1 | export * from './creator' |
2 | export * from './url-to-object' | ||
3 | export * from './object-to-model-attributes' | 2 | export * from './object-to-model-attributes' |
3 | export * from './url-to-object' | ||
diff --git a/server/lib/activitypub/actors/webfinger.ts b/server/lib/activitypub/actors/webfinger.ts new file mode 100644 index 000000000..cf8eddfc7 --- /dev/null +++ b/server/lib/activitypub/actors/webfinger.ts | |||
@@ -0,0 +1,67 @@ | |||
1 | import * as WebFinger from 'webfinger.js' | ||
2 | import { isTestInstance } from '@server/helpers/core-utils' | ||
3 | import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc' | ||
4 | import { WEBSERVER } from '@server/initializers/constants' | ||
5 | import { ActorModel } from '@server/models/actor/actor' | ||
6 | import { MActorFull } from '@server/types/models' | ||
7 | import { WebFingerData } from '@shared/models' | ||
8 | |||
9 | const webfinger = new WebFinger({ | ||
10 | webfist_fallback: false, | ||
11 | tls_only: isTestInstance(), | ||
12 | uri_fallback: false, | ||
13 | request_timeout: 3000 | ||
14 | }) | ||
15 | |||
16 | async function loadActorUrlOrGetFromWebfinger (uriArg: string) { | ||
17 | // Handle strings like @toto@example.com | ||
18 | const uri = uriArg.startsWith('@') ? uriArg.slice(1) : uriArg | ||
19 | |||
20 | const [ name, host ] = uri.split('@') | ||
21 | let actor: MActorFull | ||
22 | |||
23 | if (!host || host === WEBSERVER.HOST) { | ||
24 | actor = await ActorModel.loadLocalByName(name) | ||
25 | } else { | ||
26 | actor = await ActorModel.loadByNameAndHost(name, host) | ||
27 | } | ||
28 | |||
29 | if (actor) return actor.url | ||
30 | |||
31 | return getUrlFromWebfinger(uri) | ||
32 | } | ||
33 | |||
34 | async function getUrlFromWebfinger (uri: string) { | ||
35 | const webfingerData: WebFingerData = await webfingerLookup(uri) | ||
36 | return getLinkOrThrow(webfingerData) | ||
37 | } | ||
38 | |||
39 | // --------------------------------------------------------------------------- | ||
40 | |||
41 | export { | ||
42 | getUrlFromWebfinger, | ||
43 | loadActorUrlOrGetFromWebfinger | ||
44 | } | ||
45 | |||
46 | // --------------------------------------------------------------------------- | ||
47 | |||
48 | function getLinkOrThrow (webfingerData: WebFingerData) { | ||
49 | if (Array.isArray(webfingerData.links) === false) throw new Error('WebFinger links is not an array.') | ||
50 | |||
51 | const selfLink = webfingerData.links.find(l => l.rel === 'self') | ||
52 | if (selfLink === undefined || isActivityPubUrlValid(selfLink.href) === false) { | ||
53 | throw new Error('Cannot find self link or href is not a valid URL.') | ||
54 | } | ||
55 | |||
56 | return selfLink.href | ||
57 | } | ||
58 | |||
59 | function webfingerLookup (nameWithHost: string) { | ||
60 | return new Promise<WebFingerData>((res, rej) => { | ||
61 | webfinger.lookup(nameWithHost, (err, p) => { | ||
62 | if (err) return rej(err) | ||
63 | |||
64 | return res(p.object) | ||
65 | }) | ||
66 | }) | ||
67 | } | ||
diff --git a/server/lib/activitypub/videos/get.ts b/server/lib/activitypub/videos/get.ts index a8c41e178..38ba4978c 100644 --- a/server/lib/activitypub/videos/get.ts +++ b/server/lib/activitypub/videos/get.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { getAPId } from '@server/helpers/activitypub' | 1 | import { getAPId } from '@server/helpers/activitypub' |
2 | import { retryTransactionWrapper } from '@server/helpers/database-utils' | 2 | import { retryTransactionWrapper } from '@server/helpers/database-utils' |
3 | import { fetchVideoByUrl, VideoFetchByUrlType } from '@server/helpers/video' | ||
4 | import { JobQueue } from '@server/lib/job-queue' | 3 | import { JobQueue } from '@server/lib/job-queue' |
4 | import { fetchVideoByUrl, VideoFetchByUrlType } from '@server/lib/model-loaders' | ||
5 | import { MVideoAccountLightBlacklistAllFiles, MVideoImmutable, MVideoThumbnail } from '@server/types/models' | 5 | import { MVideoAccountLightBlacklistAllFiles, MVideoImmutable, MVideoThumbnail } from '@server/types/models' |
6 | import { refreshVideoIfNeeded } from './refresh' | 6 | import { refreshVideoIfNeeded } from './refresh' |
7 | import { APVideoCreator, fetchRemoteVideo, SyncParam, syncVideoExternalAttributes } from './shared' | 7 | import { APVideoCreator, fetchRemoteVideo, SyncParam, syncVideoExternalAttributes } from './shared' |
diff --git a/server/lib/activitypub/videos/refresh.ts b/server/lib/activitypub/videos/refresh.ts index 71a4e75b0..f1a3a6fac 100644 --- a/server/lib/activitypub/videos/refresh.ts +++ b/server/lib/activitypub/videos/refresh.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { logger, loggerTagsFactory } from '@server/helpers/logger' | 1 | import { logger, loggerTagsFactory } from '@server/helpers/logger' |
2 | import { PeerTubeRequestError } from '@server/helpers/requests' | 2 | import { PeerTubeRequestError } from '@server/helpers/requests' |
3 | import { VideoFetchByUrlType } from '@server/helpers/video' | ||
4 | import { ActorFollowScoreCache } from '@server/lib/files-cache' | 3 | import { ActorFollowScoreCache } from '@server/lib/files-cache' |
4 | import { VideoFetchByUrlType } from '@server/lib/model-loaders' | ||
5 | import { VideoModel } from '@server/models/video/video' | 5 | import { VideoModel } from '@server/models/video/video' |
6 | import { MVideoAccountLightBlacklistAllFiles, MVideoThumbnail } from '@server/types/models' | 6 | import { MVideoAccountLightBlacklistAllFiles, MVideoThumbnail } from '@server/types/models' |
7 | import { HttpStatusCode } from '@shared/core-utils' | 7 | import { HttpStatusCode } from '@shared/core-utils' |
diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts index 76b6fcaae..f896d7af4 100644 --- a/server/lib/job-queue/handlers/activitypub-follow.ts +++ b/server/lib/job-queue/handlers/activitypub-follow.ts | |||
@@ -4,13 +4,12 @@ import { ActivitypubFollowPayload } from '@shared/models' | |||
4 | import { sanitizeHost } from '../../../helpers/core-utils' | 4 | import { sanitizeHost } from '../../../helpers/core-utils' |
5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
6 | import { logger } from '../../../helpers/logger' | 6 | import { logger } from '../../../helpers/logger' |
7 | import { loadActorUrlOrGetFromWebfinger } from '../../../helpers/webfinger' | ||
8 | import { REMOTE_SCHEME, WEBSERVER } from '../../../initializers/constants' | 7 | import { REMOTE_SCHEME, WEBSERVER } from '../../../initializers/constants' |
9 | import { sequelizeTypescript } from '../../../initializers/database' | 8 | import { sequelizeTypescript } from '../../../initializers/database' |
10 | import { ActorModel } from '../../../models/actor/actor' | 9 | import { ActorModel } from '../../../models/actor/actor' |
11 | import { ActorFollowModel } from '../../../models/actor/actor-follow' | 10 | import { ActorFollowModel } from '../../../models/actor/actor-follow' |
12 | import { MActor, MActorFollowActors, MActorFull } from '../../../types/models' | 11 | import { MActor, MActorFollowActors, MActorFull } from '../../../types/models' |
13 | import { getOrCreateAPActor } from '../../activitypub/actors' | 12 | import { getOrCreateAPActor, loadActorUrlOrGetFromWebfinger } from '../../activitypub/actors' |
14 | import { sendFollow } from '../../activitypub/send' | 13 | import { sendFollow } from '../../activitypub/send' |
15 | import { Notifier } from '../../notifier' | 14 | import { Notifier } from '../../notifier' |
16 | 15 | ||
diff --git a/server/lib/job-queue/handlers/activitypub-refresher.ts b/server/lib/job-queue/handlers/activitypub-refresher.ts index 29483f310..2508a4793 100644 --- a/server/lib/job-queue/handlers/activitypub-refresher.ts +++ b/server/lib/job-queue/handlers/activitypub-refresher.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { refreshVideoPlaylistIfNeeded } from '@server/lib/activitypub/playlists' | 2 | import { refreshVideoPlaylistIfNeeded } from '@server/lib/activitypub/playlists' |
3 | import { refreshVideoIfNeeded } from '@server/lib/activitypub/videos' | 3 | import { refreshVideoIfNeeded } from '@server/lib/activitypub/videos' |
4 | import { fetchVideoByUrl } from '@server/lib/model-loaders' | ||
4 | import { RefreshPayload } from '@shared/models' | 5 | import { RefreshPayload } from '@shared/models' |
5 | import { logger } from '../../../helpers/logger' | 6 | import { logger } from '../../../helpers/logger' |
6 | import { fetchVideoByUrl } from '../../../helpers/video' | ||
7 | import { ActorModel } from '../../../models/actor/actor' | 7 | import { ActorModel } from '../../../models/actor/actor' |
8 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' | 8 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' |
9 | import { refreshActorIfNeeded } from '../../activitypub/actors' | 9 | import { refreshActorIfNeeded } from '../../activitypub/actors' |
diff --git a/server/lib/model-loaders/actor.ts b/server/lib/model-loaders/actor.ts new file mode 100644 index 000000000..234cb344f --- /dev/null +++ b/server/lib/model-loaders/actor.ts | |||
@@ -0,0 +1,16 @@ | |||
1 | |||
2 | import { ActorModel } from '../../models/actor/actor' | ||
3 | import { MActorAccountChannelId, MActorFull } from '../../types/models' | ||
4 | |||
5 | type ActorFetchByUrlType = 'all' | 'association-ids' | ||
6 | |||
7 | function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Promise<MActorFull | MActorAccountChannelId> { | ||
8 | if (fetchType === 'all') return ActorModel.loadByUrlAndPopulateAccountAndChannel(url) | ||
9 | |||
10 | if (fetchType === 'association-ids') return ActorModel.loadByUrl(url) | ||
11 | } | ||
12 | |||
13 | export { | ||
14 | ActorFetchByUrlType, | ||
15 | fetchActorByUrl | ||
16 | } | ||
diff --git a/server/lib/model-loaders/index.ts b/server/lib/model-loaders/index.ts new file mode 100644 index 000000000..9e5152cb2 --- /dev/null +++ b/server/lib/model-loaders/index.ts | |||
@@ -0,0 +1,2 @@ | |||
1 | export * from './actor' | ||
2 | export * from './video' | ||
diff --git a/server/lib/model-loaders/video.ts b/server/lib/model-loaders/video.ts new file mode 100644 index 000000000..7aaf00e89 --- /dev/null +++ b/server/lib/model-loaders/video.ts | |||
@@ -0,0 +1,64 @@ | |||
1 | import { VideoModel } from '@server/models/video/video' | ||
2 | import { | ||
3 | MVideoAccountLightBlacklistAllFiles, | ||
4 | MVideoFullLight, | ||
5 | MVideoIdThumbnail, | ||
6 | MVideoImmutable, | ||
7 | MVideoThumbnail, | ||
8 | MVideoWithRights | ||
9 | } from '@server/types/models' | ||
10 | |||
11 | type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes' | ||
12 | |||
13 | function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Promise<MVideoFullLight> | ||
14 | function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable> | ||
15 | function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Promise<MVideoThumbnail> | ||
16 | function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Promise<MVideoWithRights> | ||
17 | function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Promise<MVideoIdThumbnail> | ||
18 | function fetchVideo ( | ||
19 | id: number | string, | ||
20 | fetchType: VideoFetchType, | ||
21 | userId?: number | ||
22 | ): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable> | ||
23 | function fetchVideo ( | ||
24 | id: number | string, | ||
25 | fetchType: VideoFetchType, | ||
26 | userId?: number | ||
27 | ): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable> { | ||
28 | if (fetchType === 'all') return VideoModel.loadAndPopulateAccountAndServerAndTags(id, undefined, userId) | ||
29 | |||
30 | if (fetchType === 'only-immutable-attributes') return VideoModel.loadImmutableAttributes(id) | ||
31 | |||
32 | if (fetchType === 'only-video-with-rights') return VideoModel.loadWithRights(id) | ||
33 | |||
34 | if (fetchType === 'only-video') return VideoModel.load(id) | ||
35 | |||
36 | if (fetchType === 'id' || fetchType === 'none') return VideoModel.loadOnlyId(id) | ||
37 | } | ||
38 | |||
39 | type VideoFetchByUrlType = 'all' | 'only-video' | 'only-immutable-attributes' | ||
40 | |||
41 | function fetchVideoByUrl (url: string, fetchType: 'all'): Promise<MVideoAccountLightBlacklistAllFiles> | ||
42 | function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable> | ||
43 | function fetchVideoByUrl (url: string, fetchType: 'only-video'): Promise<MVideoThumbnail> | ||
44 | function fetchVideoByUrl ( | ||
45 | url: string, | ||
46 | fetchType: VideoFetchByUrlType | ||
47 | ): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> | ||
48 | function fetchVideoByUrl ( | ||
49 | url: string, | ||
50 | fetchType: VideoFetchByUrlType | ||
51 | ): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> { | ||
52 | if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url) | ||
53 | |||
54 | if (fetchType === 'only-immutable-attributes') return VideoModel.loadByUrlImmutableAttributes(url) | ||
55 | |||
56 | if (fetchType === 'only-video') return VideoModel.loadByUrl(url) | ||
57 | } | ||
58 | |||
59 | export { | ||
60 | VideoFetchType, | ||
61 | VideoFetchByUrlType, | ||
62 | fetchVideo, | ||
63 | fetchVideoByUrl | ||
64 | } | ||
diff --git a/server/lib/server-config-manager.ts b/server/lib/server-config-manager.ts index 25a770c6b..80d87a9d3 100644 --- a/server/lib/server-config-manager.ts +++ b/server/lib/server-config-manager.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/helpers/signup' | ||
2 | import { getServerCommit } from '@server/helpers/utils' | 1 | import { getServerCommit } from '@server/helpers/utils' |
3 | import { CONFIG, isEmailEnabled } from '@server/initializers/config' | 2 | import { CONFIG, isEmailEnabled } from '@server/initializers/config' |
4 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' | 3 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' |
4 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/lib/signup' | ||
5 | import { ActorCustomPageModel } from '@server/models/account/actor-custom-page' | 5 | import { ActorCustomPageModel } from '@server/models/account/actor-custom-page' |
6 | import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' | 6 | import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' |
7 | import { Hooks } from './plugins/hooks' | 7 | import { Hooks } from './plugins/hooks' |
diff --git a/server/lib/signup.ts b/server/lib/signup.ts new file mode 100644 index 000000000..8fa81e601 --- /dev/null +++ b/server/lib/signup.ts | |||
@@ -0,0 +1,62 @@ | |||
1 | import { UserModel } from '../models/user/user' | ||
2 | import * as ipaddr from 'ipaddr.js' | ||
3 | import { CONFIG } from '../initializers/config' | ||
4 | |||
5 | const isCidr = require('is-cidr') | ||
6 | |||
7 | async function isSignupAllowed (): Promise<{ allowed: boolean, errorMessage?: string }> { | ||
8 | if (CONFIG.SIGNUP.ENABLED === false) { | ||
9 | return { allowed: false } | ||
10 | } | ||
11 | |||
12 | // No limit and signup is enabled | ||
13 | if (CONFIG.SIGNUP.LIMIT === -1) { | ||
14 | return { allowed: true } | ||
15 | } | ||
16 | |||
17 | const totalUsers = await UserModel.countTotal() | ||
18 | |||
19 | return { allowed: totalUsers < CONFIG.SIGNUP.LIMIT } | ||
20 | } | ||
21 | |||
22 | function isSignupAllowedForCurrentIP (ip: string) { | ||
23 | if (!ip) return false | ||
24 | |||
25 | const addr = ipaddr.parse(ip) | ||
26 | const excludeList = [ 'blacklist' ] | ||
27 | let matched = '' | ||
28 | |||
29 | // if there is a valid, non-empty whitelist, we exclude all unknown adresses too | ||
30 | if (CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr(cidr)).length > 0) { | ||
31 | excludeList.push('unknown') | ||
32 | } | ||
33 | |||
34 | if (addr.kind() === 'ipv4') { | ||
35 | const addrV4 = ipaddr.IPv4.parse(ip) | ||
36 | const rangeList = { | ||
37 | whitelist: CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr.v4(cidr)) | ||
38 | .map(cidr => ipaddr.IPv4.parseCIDR(cidr)), | ||
39 | blacklist: CONFIG.SIGNUP.FILTERS.CIDR.BLACKLIST.filter(cidr => isCidr.v4(cidr)) | ||
40 | .map(cidr => ipaddr.IPv4.parseCIDR(cidr)) | ||
41 | } | ||
42 | matched = ipaddr.subnetMatch(addrV4, rangeList, 'unknown') | ||
43 | } else if (addr.kind() === 'ipv6') { | ||
44 | const addrV6 = ipaddr.IPv6.parse(ip) | ||
45 | const rangeList = { | ||
46 | whitelist: CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr.v6(cidr)) | ||
47 | .map(cidr => ipaddr.IPv6.parseCIDR(cidr)), | ||
48 | blacklist: CONFIG.SIGNUP.FILTERS.CIDR.BLACKLIST.filter(cidr => isCidr.v6(cidr)) | ||
49 | .map(cidr => ipaddr.IPv6.parseCIDR(cidr)) | ||
50 | } | ||
51 | matched = ipaddr.subnetMatch(addrV6, rangeList, 'unknown') | ||
52 | } | ||
53 | |||
54 | return !excludeList.includes(matched) | ||
55 | } | ||
56 | |||
57 | // --------------------------------------------------------------------------- | ||
58 | |||
59 | export { | ||
60 | isSignupAllowed, | ||
61 | isSignupAllowedForCurrentIP | ||
62 | } | ||