mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-29 16:06:07 +00:00
Merge pull request #938 from qtchaos/remove-domain
Remove references to official domain
This commit is contained in:
commit
9e4241e464
2
.github/CODE_OF_CONDUCT.md
vendored
2
.github/CODE_OF_CONDUCT.md
vendored
|
@ -60,7 +60,7 @@ representative at an online or offline event.
|
|||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
codeofconduct@movie-web.app.
|
||||
our [Discord](https://discord.gg/gQYB6fGArX).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
|
|
6
.github/CONTRIBUTING.md
vendored
6
.github/CONTRIBUTING.md
vendored
|
@ -1,6 +1,6 @@
|
|||
# Contributing Guidelines for movie-web
|
||||
|
||||
Thank you for investing your time in contributing to our project! Your contribution will be reflected on [movie-web.app](https://movie-web.app).
|
||||
Thank you for investing your time in contributing to our project! Your contribution will be reflected on all of the community hosted instances that are on the latest version.
|
||||
|
||||
Please read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
|
||||
|
||||
|
@ -33,7 +33,7 @@ There are two places where to request features or report bugs:
|
|||
### Discord Server
|
||||
If you do not have a GitHub account or want to discuss a feature or bug with us before making an issue, you can join our Discord server.
|
||||
|
||||
<a href="https://discord.movie-web.app"><img src="https://discord.com/api/guilds/871713465100816424/widget.png?style=banner2" alt="Discord Server"></a>
|
||||
<a href="https://discord.gg/gQYB6fGArX"><img src="https://discord.com/api/guilds/871713465100816424/widget.png?style=banner2" alt="Discord Server"></a>
|
||||
|
||||
### GitHub Issues
|
||||
To make a GitHub issue for movie-web, please visit the [new issue page](https://github.com/movie-web/movie-web/issues/new/choose) where you can pick either the "Bug Report" or "Feature Request" template.
|
||||
|
@ -85,7 +85,7 @@ Here are some tips to make sure that your pull requests are :pinched_fingers: fi
|
|||
### Language Contributions
|
||||
Language contributions help movie-web massively, allowing people worldwide to use our app!
|
||||
|
||||
We use weblate for crowdsourcing our translations. [Click here to go to our translation tool.](https://weblate.movie-web.app/projects/movie-web/website/)
|
||||
We use weblate for crowdsourcing our translations.
|
||||
|
||||
1. First make sure you make an account. (click the link above)
|
||||
2. Click the language you want to help translate, if it's not listed you can click the plus top left to add a new language.
|
||||
|
|
9
.github/SECURITY.md
vendored
9
.github/SECURITY.md
vendored
|
@ -2,12 +2,9 @@
|
|||
|
||||
## Supported Versions
|
||||
|
||||
The movie-web maintainers only support the latest version of movie-web published at https://movie-web.app.
|
||||
|
||||
Support is not provided for any forks or mirrors of movie-web.
|
||||
The latest version of movie-web is the only version that is supported, as it is the only version that is being actively developed.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
There are two ways you can contact the movie-web maintainers to report a vulnerability:
|
||||
- Email [security@movie-web.app](mailto:security@movie-web.app)
|
||||
- Report the vulnerability in the [movie-web Discord server](https://discord.movie-web.app)
|
||||
You can contact the movie-web maintainers to report a vulnerability:
|
||||
- Report the vulnerability in the [movie-web Discord server](https://discord.gg/gQYB6fGArX)
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
<p align="center">
|
||||
<img src="https://skillicons.dev/icons?i=react,vite,ts" />
|
||||
<br/>
|
||||
<a href="https://discord.movie-web.app"><kbd>🔵 discord</kbd></a> <a href="https://movie-web.app"><kbd>🟢 website</kbd></a>
|
||||
<a href="https://discord.gg/gQYB6fGArX"><kbd>🔵 discord</kbd></a> <a href="https://movie-web.github.io/docs"><kbd>🟢 docs</kbd></a>
|
||||
</p>
|
||||
<br/><br/>
|
||||
|
||||
# ⚡What is movie-web?
|
||||
|
||||
movie-web is a web app for watching movies easily. Check it out at <a href="https://movie-web.app"><kbd>movie-web.app</kbd></a>.
|
||||
movie-web is a web app for watching movies easily.
|
||||
|
||||
This service works by displaying video files from third-party providers inside an intuitive and aesthetic user interface.
|
||||
|
||||
|
@ -57,7 +57,7 @@ pnpm build
|
|||
|
||||
A simple guide has been written to assist in hosting your own instance of movie-web. Check it out below
|
||||
|
||||
|[Selfhosting guide](https://docs.movie-web.app)|
|
||||
|[Selfhosting guide](https://movie-web.github.io/docs)|
|
||||
|---|
|
||||
|
||||
## 🤝 Thanks to all Contributors
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "movie-web",
|
||||
"version": "4.4.2",
|
||||
"private": true,
|
||||
"homepage": "https://movie-web.app",
|
||||
"homepage": "https://github.com/movie-web/movie-web",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
|
|
|
@ -11,7 +11,7 @@ window.__CONFIG__ = {
|
|||
// Whether to disable hash-based routing, leave this as false if you don't know what this is
|
||||
VITE_NORMAL_ROUTER: false,
|
||||
|
||||
// The backend URL to communicate with, defaults to the movie-web hosted one at backend.movie-web.app
|
||||
// The backend URL to communicate with
|
||||
VITE_BACKEND_URL: null,
|
||||
|
||||
// A comma separated list of disallowed IDs in the case of a DMCA claim - in the format "series-<id>" and "movie-<id>"
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
"text": "Did you configure it correctly?",
|
||||
"title": "Failed to reach server"
|
||||
},
|
||||
"noHostTitle": "Server not configured!",
|
||||
"noHost": "The server has not been configured, therefore you cannot create an account",
|
||||
"host": "You are connecting to <0>{{hostname}}</0> - please confirm you trust it before making an account",
|
||||
"no": "Go back",
|
||||
"title": "Do you trust this server?",
|
||||
|
|
|
@ -5,13 +5,14 @@ import { useCallback } from "react";
|
|||
|
||||
import { isExtensionActiveCached } from "@/backend/extension/messaging";
|
||||
import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape";
|
||||
import { BACKEND_URL } from "@/setup/constants";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { PlayerMeta } from "@/stores/player/slices/source";
|
||||
|
||||
// for anybody who cares - these are anonymous metrics.
|
||||
// They are just used for figuring out if providers are broken or not
|
||||
const metricsEndpoint = "https://backend.movie-web.app/metrics/providers";
|
||||
const captchaMetricsEndpoint = "https://backend.movie-web.app/metrics/captcha";
|
||||
const metricsEndpoint = `${BACKEND_URL}/metrics/providers`;
|
||||
const captchaMetricsEndpoint = `${BACKEND_URL}/metrics/captcha`;
|
||||
const batchId = () => nanoid(32);
|
||||
|
||||
export type ProviderMetric = {
|
||||
|
@ -44,6 +45,7 @@ function getStackTrace(error: Error, lines: number) {
|
|||
}
|
||||
|
||||
export async function reportProviders(items: ProviderMetric[]): Promise<void> {
|
||||
if (!BACKEND_URL) return;
|
||||
return ofetch(metricsEndpoint, {
|
||||
method: "POST",
|
||||
body: {
|
||||
|
@ -156,6 +158,7 @@ export function useReportProviders() {
|
|||
}
|
||||
|
||||
export function reportCaptchaSolve(success: boolean) {
|
||||
if (!BACKEND_URL) return;
|
||||
ofetch(captchaMetricsEndpoint, {
|
||||
method: "POST",
|
||||
body: {
|
||||
|
|
|
@ -63,6 +63,7 @@ export function useAuth() {
|
|||
|
||||
const login = useCallback(
|
||||
async (loginData: LoginData) => {
|
||||
if (!backendUrl) return;
|
||||
const keys = await keysFromMnemonic(loginData.mnemonic);
|
||||
const publicKeyBase64Url = bytesToBase64Url(keys.publicKey);
|
||||
const { challenge } = await getLoginChallengeToken(
|
||||
|
@ -87,7 +88,7 @@ export function useAuth() {
|
|||
);
|
||||
|
||||
const logout = useCallback(async () => {
|
||||
if (!currentAccount) return;
|
||||
if (!currentAccount || !backendUrl) return;
|
||||
try {
|
||||
await removeSession(
|
||||
backendUrl,
|
||||
|
@ -102,6 +103,7 @@ export function useAuth() {
|
|||
|
||||
const register = useCallback(
|
||||
async (registerData: RegistrationData) => {
|
||||
if (!backendUrl) return;
|
||||
const { challenge } = await getRegisterChallengeToken(
|
||||
backendUrl,
|
||||
registerData.recaptchaToken,
|
||||
|
@ -134,6 +136,7 @@ export function useAuth() {
|
|||
progressItems: Record<string, ProgressMediaItem>,
|
||||
bookmarks: Record<string, BookmarkMediaItem>,
|
||||
) => {
|
||||
if (!backendUrl) return;
|
||||
if (
|
||||
Object.keys(progressItems).length === 0 &&
|
||||
Object.keys(bookmarks).length === 0
|
||||
|
@ -159,6 +162,7 @@ export function useAuth() {
|
|||
|
||||
const restore = useCallback(
|
||||
async (account: AccountWithToken) => {
|
||||
if (!backendUrl) return;
|
||||
let user: { user: UserResponse; session: SessionResponse };
|
||||
try {
|
||||
user = await getUser(backendUrl, account.token);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { conf } from "@/setup/config";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
export function useBackendUrl() {
|
||||
export function useBackendUrl(): string | undefined {
|
||||
const backendUrl = useAuthStore((s) => s.backendUrl);
|
||||
return backendUrl ?? conf().BACKEND_URL;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ export function AccountSettings(props: {
|
|||
const url = useBackendUrl();
|
||||
const { account } = props;
|
||||
const [sessionsResult, execSessions] = useAsyncFn(() => {
|
||||
if (!url) return Promise.resolve([]);
|
||||
return getSessions(url, account);
|
||||
}, [account, url]);
|
||||
useEffect(() => {
|
||||
|
@ -144,7 +145,7 @@ export function SettingsPage() {
|
|||
);
|
||||
|
||||
const saveChanges = useCallback(async () => {
|
||||
if (account) {
|
||||
if (account && backendUrl) {
|
||||
if (
|
||||
state.appLanguage.changed ||
|
||||
state.theme.changed ||
|
||||
|
|
|
@ -43,7 +43,7 @@ export function OnboardingProxyPage() {
|
|||
throw new Error("onboarding.proxy.input.errorNotProxy");
|
||||
setProxySet([url]);
|
||||
|
||||
if (account) {
|
||||
if (account && backendUrl) {
|
||||
await updateSettings(backendUrl, account, {
|
||||
proxyUrls: [url],
|
||||
});
|
||||
|
|
|
@ -32,13 +32,21 @@ export function BackendTestPart() {
|
|||
value: null,
|
||||
});
|
||||
|
||||
if (!backendUrl) {
|
||||
return setStatus({
|
||||
hasTested: true,
|
||||
success: false,
|
||||
errorText: "Backend URL is not set",
|
||||
value: null,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const backendData = await getBackendMeta(backendUrl);
|
||||
return setStatus({
|
||||
hasTested: true,
|
||||
success: true,
|
||||
errorText:
|
||||
"Failed to call backend, double check the URL key and your internet connection",
|
||||
errorText: "",
|
||||
value: backendData,
|
||||
});
|
||||
} catch (err) {
|
||||
|
@ -46,7 +54,7 @@ export function BackendTestPart() {
|
|||
hasTested: true,
|
||||
success: false,
|
||||
errorText:
|
||||
"Failed to call backend, double check the URL key and your internet connection",
|
||||
"Failed to call backend, double check the URL, your internet connection, and ensure CORS is properly configured on your backend.",
|
||||
value: null,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,6 +52,9 @@ export function LoginFormPart(props: LoginFormPartProps) {
|
|||
throw err;
|
||||
}
|
||||
|
||||
if (!account)
|
||||
throw new Error(t("auth.login.validationError") ?? undefined);
|
||||
|
||||
await importData(account, progressItems, bookmarkItems);
|
||||
|
||||
await restore(account);
|
||||
|
|
|
@ -22,8 +22,12 @@ interface TrustBackendPartProps {
|
|||
export function TrustBackendPart(props: TrustBackendPartProps) {
|
||||
const navigate = useNavigate();
|
||||
const backendUrl = useBackendUrl();
|
||||
const hostname = useMemo(() => new URL(backendUrl).hostname, [backendUrl]);
|
||||
const hostname = useMemo(
|
||||
() => (backendUrl ? new URL(backendUrl).hostname : undefined),
|
||||
[backendUrl],
|
||||
);
|
||||
const result = useAsync(() => {
|
||||
if (!backendUrl) return Promise.resolve(null);
|
||||
return getBackendMeta(backendUrl);
|
||||
}, [backendUrl]);
|
||||
const { t } = useTranslation();
|
||||
|
@ -50,38 +54,52 @@ export function TrustBackendPart(props: TrustBackendPartProps) {
|
|||
return (
|
||||
<LargeCard>
|
||||
<LargeCardText
|
||||
title={t("auth.trust.title")}
|
||||
title={hostname ? t("auth.trust.title") : t("auth.trust.noHostTitle")}
|
||||
icon={<Icon icon={Icons.CIRCLE_EXCLAMATION} />}
|
||||
>
|
||||
<Trans
|
||||
i18nKey="auth.trust.host"
|
||||
values={{
|
||||
hostname,
|
||||
}}
|
||||
>
|
||||
<span className="text-white" />
|
||||
</Trans>
|
||||
{hostname ? (
|
||||
<Trans
|
||||
i18nKey="auth.trust.host"
|
||||
values={{
|
||||
hostname,
|
||||
}}
|
||||
>
|
||||
<span className="text-white" />
|
||||
</Trans>
|
||||
) : (
|
||||
<p>{t("auth.trust.noHost")}</p>
|
||||
)}
|
||||
</LargeCardText>
|
||||
|
||||
<div className="border border-authentication-border rounded-xl px-4 py-8 flex flex-col items-center space-y-2 my-8">
|
||||
{cardContent}
|
||||
</div>
|
||||
<LargeCardButtons>
|
||||
<Button theme="secondary" onClick={() => navigate("/")}>
|
||||
{t("auth.trust.no")}
|
||||
</Button>
|
||||
<Button
|
||||
theme="purple"
|
||||
onClick={() => result.value && props.onNext?.(result.value)}
|
||||
>
|
||||
{t("auth.trust.yes")}
|
||||
</Button>
|
||||
</LargeCardButtons>
|
||||
<p className="text-center mt-6">
|
||||
<Trans i18nKey="auth.hasAccount">
|
||||
<MwLink to="/login">.</MwLink>
|
||||
</Trans>
|
||||
</p>
|
||||
{hostname ? (
|
||||
<>
|
||||
<div className="border border-authentication-border rounded-xl px-4 py-8 flex flex-col items-center space-y-2 my-8">
|
||||
{cardContent}
|
||||
</div>
|
||||
<LargeCardButtons>
|
||||
<Button theme="secondary" onClick={() => navigate("/")}>
|
||||
{t("auth.trust.no")}
|
||||
</Button>
|
||||
<Button
|
||||
theme="purple"
|
||||
onClick={() => result.value && props.onNext?.(result.value)}
|
||||
>
|
||||
{t("auth.trust.yes")}
|
||||
</Button>
|
||||
</LargeCardButtons>
|
||||
<p className="text-center mt-6">
|
||||
<Trans i18nKey="auth.hasAccount">
|
||||
<MwLink to="/login">.</MwLink>
|
||||
</Trans>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<LargeCardButtons>
|
||||
<Button theme="purple" onClick={() => navigate("/")}>
|
||||
{t("auth.trust.no")}
|
||||
</Button>
|
||||
</LargeCardButtons>
|
||||
)}
|
||||
</LargeCard>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
|||
|
||||
const [result, execute] = useAsyncFn(
|
||||
async (inputMnemonic: string) => {
|
||||
if (!backendUrl)
|
||||
throw new Error(t("auth.verify.noBackendUrl") ?? undefined);
|
||||
if (!props.mnemonic || !props.userData)
|
||||
throw new Error(t("auth.verify.invalidData") ?? undefined);
|
||||
|
||||
|
@ -68,6 +70,9 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
|||
recaptchaToken,
|
||||
});
|
||||
|
||||
if (!account)
|
||||
throw new Error(t("auth.verify.registrationFailed") ?? undefined);
|
||||
|
||||
await importData(account, progressItems, bookmarkItems);
|
||||
|
||||
await updateSettings(backendUrl, account, {
|
||||
|
|
|
@ -18,7 +18,7 @@ export function AccountActionsPart() {
|
|||
const deleteModal = useModal("account-delete");
|
||||
|
||||
const [deleteResult, deleteExec] = useAsyncFn(async () => {
|
||||
if (!account) return;
|
||||
if (!account || !url) return;
|
||||
await deleteUser(url, account);
|
||||
await logout();
|
||||
deleteModal.hide();
|
||||
|
|
|
@ -55,7 +55,7 @@ function ProxyEdit({ proxyUrls, setProxyUrls }: ProxyEditProps) {
|
|||
</p>
|
||||
<p className="max-w-[20rem] font-medium">
|
||||
<Trans i18nKey="settings.connections.workers.description">
|
||||
<MwLink to="https://docs.movie-web.app/proxy/deploy">
|
||||
<MwLink to="https://movie-web.github.io/docs/proxy/deploy">
|
||||
Proxy documentation
|
||||
</MwLink>
|
||||
</Trans>
|
||||
|
@ -125,7 +125,7 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
|
|||
</p>
|
||||
<p className="max-w-[20rem] font-medium">
|
||||
<Trans i18nKey="settings.connections.server.description">
|
||||
<MwLink to="https://docs.movie-web.app/backend/deploy">
|
||||
<MwLink to="https://movie-web.github.io/docs/backend/deploy">
|
||||
Backend documentation
|
||||
</MwLink>
|
||||
</Trans>
|
||||
|
|
|
@ -24,6 +24,7 @@ export function Device(props: {
|
|||
const token = useAuthStore((s) => s.account?.token);
|
||||
const [result, exec] = useAsyncFn(async () => {
|
||||
if (!token) throw new Error("No token present");
|
||||
if (!url) throw new Error("No backend set");
|
||||
await removeSession(url, token, props.id);
|
||||
props.onRemove?.();
|
||||
}, [url, token, props.id]);
|
||||
|
|
|
@ -14,9 +14,9 @@ import { useAuthStore } from "@/stores/auth";
|
|||
|
||||
const rem = 16;
|
||||
|
||||
function SecureBadge(props: { url: string }) {
|
||||
function SecureBadge(props: { url: string | undefined }) {
|
||||
const { t } = useTranslation();
|
||||
const secure = props.url.startsWith("https://");
|
||||
const secure = props.url ? props.url.startsWith("https://") : false;
|
||||
return (
|
||||
<div className="flex items-center gap-1 -mx-1 ml-3 px-1 rounded bg-largeCard-background font-bold">
|
||||
<Icon icon={secure ? Icons.LOCK : Icons.UNLOCK} />
|
||||
|
@ -68,6 +68,7 @@ export function SidebarPart() {
|
|||
const backendUrl = useBackendUrl();
|
||||
|
||||
const backendMeta = useAsync(async () => {
|
||||
if (!backendUrl) return;
|
||||
return getBackendMeta(backendUrl);
|
||||
}, [backendUrl]);
|
||||
|
||||
|
@ -159,7 +160,7 @@ export function SidebarPart() {
|
|||
<SecureBadge url={backendUrl} />
|
||||
</div>
|
||||
<p className="text-white">
|
||||
{backendUrl.replace(/https?:\/\//, "")}
|
||||
{backendUrl?.replace(/https?:\/\//, "") ?? "—"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export const APP_VERSION = import.meta.env.PACKAGE_VERSION;
|
||||
export const DISCORD_LINK = "https://discord.movie-web.app";
|
||||
export const DISCORD_LINK = "https://discord.gg/gQYB6fGArX";
|
||||
export const GITHUB_LINK = "https://github.com/movie-web/movie-web";
|
||||
export const DONATION_LINK = "https://ko-fi.com/movieweb";
|
||||
export const GA_ID = "G-44YVXRL61C";
|
||||
export const BACKEND_URL = "https://backend.movie-web.app";
|
||||
export const BACKEND_URL = import.meta.env.VITE_BACKEND_URL;
|
||||
|
|
|
@ -60,6 +60,7 @@ export function BookmarkSyncer() {
|
|||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
(async () => {
|
||||
if (!url) return;
|
||||
const state = useBookmarkStore.getState();
|
||||
const user = useAuthStore.getState();
|
||||
await syncBookmarks(
|
||||
|
|
|
@ -62,6 +62,7 @@ export function ProgressSyncer() {
|
|||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
(async () => {
|
||||
if (!url) return;
|
||||
const state = useProgressStore.getState();
|
||||
const user = useAuthStore.getState();
|
||||
await syncProgress(
|
||||
|
|
|
@ -16,6 +16,7 @@ export function SettingsSyncer() {
|
|||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
(async () => {
|
||||
if (!url) return;
|
||||
const state = useSubtitleStore.getState();
|
||||
const user = useAuthStore.getState();
|
||||
if (state.lastSync.lastSelectedLanguage === state.lastSelectedLanguage)
|
||||
|
|
Loading…
Reference in a new issue