feat(legal): integrate privacy policy and terms of service into the application, #3577
- Added a new internal package for legal documents, including privacy policy and terms of service. - Implemented a build script to convert markdown files to HTML for easy access. - Updated the mobile and desktop applications to link to the new legal documents. - Enhanced the login modal to include links to the privacy policy and terms of service. - Updated routing in the SSR application to serve the legal documents. These changes ensure compliance with legal requirements and improve user access to important information. Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
parent
e2c3bdd3d2
commit
e69d120bd9
|
|
@ -0,0 +1,25 @@
|
|||
import { legalHtml } from "@follow/legal"
|
||||
import { stopPropagation } from "@follow/utils/dom"
|
||||
import { m } from "motion/react"
|
||||
import type { FC } from "react"
|
||||
|
||||
type LegalModalProps = {
|
||||
type: "privacy" | "tos"
|
||||
}
|
||||
|
||||
export const LegalModalContent: FC<LegalModalProps> = ({ type }) => {
|
||||
const content = type === "privacy" ? legalHtml.privacy : legalHtml.tos
|
||||
|
||||
return (
|
||||
<m.div className="size-full overflow-hidden">
|
||||
<div className="bg-background size-full overflow-auto rounded-lg" onClick={stopPropagation}>
|
||||
<iframe
|
||||
sandbox="allow-scripts"
|
||||
srcDoc={content}
|
||||
title={type === "privacy" ? "Privacy Policy" : "Terms of Service"}
|
||||
className="size-full border-0"
|
||||
/>
|
||||
</div>
|
||||
</m.div>
|
||||
)
|
||||
}
|
||||
|
|
@ -10,11 +10,12 @@ import { m } from "motion/react"
|
|||
import { useState } from "react"
|
||||
import { Trans, useTranslation } from "react-i18next"
|
||||
|
||||
import { useCurrentModal } from "~/components/ui/modal/stacked/hooks"
|
||||
import { useCurrentModal, useModalStack } from "~/components/ui/modal/stacked/hooks"
|
||||
import { loginHandler } from "~/lib/auth"
|
||||
import { useAuthProviders } from "~/queries/users"
|
||||
|
||||
import { LoginWithPassword, RegisterForm } from "./Form"
|
||||
import { LegalModalContent } from "./LegalModal"
|
||||
|
||||
interface LoginModalContentProps {
|
||||
runtime: LoginRuntime
|
||||
|
|
@ -23,6 +24,7 @@ interface LoginModalContentProps {
|
|||
|
||||
export const LoginModalContent = (props: LoginModalContentProps) => {
|
||||
const modal = useCurrentModal()
|
||||
const { present } = useModalStack()
|
||||
|
||||
const { canClose = true, runtime } = props
|
||||
|
||||
|
|
@ -36,6 +38,17 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
|
|||
const [isRegister, setIsRegister] = useState(true)
|
||||
const [isEmail, setIsEmail] = useState(false)
|
||||
|
||||
const handleOpenLegal = (type: "privacy" | "tos") => {
|
||||
present({
|
||||
id: `legal-${type}`,
|
||||
title: type === "privacy" ? t("login.privacy") : t("login.terms"),
|
||||
content: () => <LegalModalContent type={type} />,
|
||||
resizeable: true,
|
||||
clickOutsideToDismiss: true,
|
||||
max: true,
|
||||
})
|
||||
}
|
||||
|
||||
const Inner = (
|
||||
<>
|
||||
<div className="-mt-9 mb-4 flex items-center justify-center">
|
||||
|
|
@ -103,6 +116,23 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
|
|||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="text-text-secondary mt-3 text-center text-xs leading-5">
|
||||
<span>{t("login.agree_to")}</span> <br />
|
||||
<a
|
||||
onClick={() => handleOpenLegal("tos")}
|
||||
className="text-accent cursor-pointer hover:underline"
|
||||
>
|
||||
{t("login.terms")}
|
||||
</a>{" "}
|
||||
&{" "}
|
||||
<a
|
||||
onClick={() => handleOpenLegal("privacy")}
|
||||
className="text-accent cursor-pointer hover:underline"
|
||||
>
|
||||
{t("login.privacy")}
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
if (isMobile) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
"@follow/configs": "workspace:*",
|
||||
"@follow/constants": "workspace:*",
|
||||
"@follow/hooks": "workspace:*",
|
||||
"@follow/legal": "workspace:*",
|
||||
"@follow/models": "workspace:*",
|
||||
"@follow/shared": "workspace:*",
|
||||
"@follow/utils": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
"@follow/components": "workspace:*",
|
||||
"@follow/constants": "workspace:*",
|
||||
"@follow/hooks": "workspace:*",
|
||||
"@follow/legal": "workspace:*",
|
||||
"@follow/models": "workspace:*",
|
||||
"@follow/shared": "workspace:*",
|
||||
"@follow/tracker": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { Logo } from "@/src/components/ui/logo"
|
|||
import { useNavigation } from "@/src/lib/navigation/hooks"
|
||||
import { NavigationLink } from "@/src/lib/navigation/NavigationLink"
|
||||
import { useScaleHeight } from "@/src/lib/responsive"
|
||||
import { PrivacyPolicyScreen } from "@/src/screens/(headless)/privacy"
|
||||
import { TermsMarkdown, TermsScreen } from "@/src/screens/(headless)/terms"
|
||||
|
||||
import { EmailLogin, EmailSignUp } from "./email"
|
||||
|
|
@ -110,16 +111,26 @@ const TermsText = () => {
|
|||
return (
|
||||
<ContextMenu.Root>
|
||||
<ContextMenu.Trigger className="w-full overflow-hidden rounded-full">
|
||||
<Text className="text-secondary-label text-sm">
|
||||
<Text className="text-secondary-label text-center text-sm">
|
||||
By continuing, you agree to our{" "}
|
||||
</Text>
|
||||
<View className="flex-row items-center">
|
||||
<NavigationLink
|
||||
destination={TermsScreen}
|
||||
suppressHighlighting
|
||||
className="text-primary-label"
|
||||
className="text-secondary-label"
|
||||
>
|
||||
<Text className="font-semibold">Terms of Service</Text>
|
||||
</NavigationLink>
|
||||
</Text>
|
||||
<Text className="text-secondary-label"> & </Text>
|
||||
<NavigationLink
|
||||
destination={PrivacyPolicyScreen}
|
||||
suppressHighlighting
|
||||
className="text-secondary-label"
|
||||
>
|
||||
<Text className="font-semibold">Privacy Policy</Text>
|
||||
</NavigationLink>
|
||||
</View>
|
||||
</ContextMenu.Trigger>
|
||||
|
||||
<ContextMenu.Content>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
GroupedInsetListNavigationLink,
|
||||
} from "@/src/components/ui/grouped/GroupedList"
|
||||
import { useNavigation } from "@/src/lib/navigation/hooks"
|
||||
import { PrivacyPolicyScreen } from "@/src/screens/(headless)/privacy"
|
||||
import { TermsScreen } from "@/src/screens/(headless)/terms"
|
||||
|
||||
export const PrivacyScreen = () => {
|
||||
|
|
@ -26,6 +27,12 @@ export const PrivacyScreen = () => {
|
|||
pushControllerView(TermsScreen)
|
||||
}}
|
||||
/>
|
||||
<GroupedInsetListNavigationLink
|
||||
label={t("privacy.privacy")}
|
||||
onPress={() => {
|
||||
pushControllerView(PrivacyPolicyScreen)
|
||||
}}
|
||||
/>
|
||||
</GroupedInsetListCard>
|
||||
</SafeNavigationScrollView>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
import { legalMarkdown } from "@follow/legal/dist/index"
|
||||
|
||||
import {
|
||||
NavigationBlurEffectHeaderView,
|
||||
SafeNavigationScrollView,
|
||||
} from "@/src/components/layouts/views/SafeNavigationScrollView"
|
||||
import { Markdown } from "@/src/components/ui/typography/Markdown"
|
||||
import type { NavigationControllerView } from "@/src/lib/navigation/types"
|
||||
|
||||
export const PrivacyMarkdown = () => {
|
||||
return (
|
||||
<Markdown
|
||||
value={legalMarkdown.privacy}
|
||||
webViewProps={{ scrollEnabled: false, matchContents: true }}
|
||||
style={{ padding: 16, flex: 1 }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const PrivacyPolicyScreen: NavigationControllerView = () => {
|
||||
return (
|
||||
<SafeNavigationScrollView
|
||||
className="bg-system-background"
|
||||
contentInsetAdjustmentBehavior="never"
|
||||
Header={<NavigationBlurEffectHeaderView title="Privacy Policy" />}
|
||||
>
|
||||
<PrivacyMarkdown />
|
||||
</SafeNavigationScrollView>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { legalMarkdown } from "@follow/legal/dist/index"
|
||||
|
||||
import {
|
||||
NavigationBlurEffectHeaderView,
|
||||
SafeNavigationScrollView,
|
||||
|
|
@ -5,87 +7,10 @@ import {
|
|||
import { Markdown } from "@/src/components/ui/typography/Markdown"
|
||||
import type { NavigationControllerView } from "@/src/lib/navigation/types"
|
||||
|
||||
const txt = `# Terms of Service
|
||||
|
||||
**Effective Date:** 2025-01-17
|
||||
|
||||
Welcome to Folo, your personalized RSS reader and content hub. By using our application, you agree to these Terms of Service ("Terms"). Please read them carefully as they govern your use of the Service and the rights and obligations that come with it.
|
||||
|
||||
Folo is designed to give you an intuitive, efficient, and user-friendly experience in managing your RSS feeds. We aim to provide a seamless and secure environment, but it’s important for you to understand how your rights are protected and the scope of your responsibilities while using the Service.
|
||||
|
||||
## 1. Acceptance of Terms
|
||||
By accessing or using Folo ("the Service"), you agree to comply with and be bound by these Terms and our Privacy Policy. If you do not agree to these Terms, you may not use the Service. These Terms are a legally binding contract between you and Natural Selection Limited, which owns and operates Folo. By using the Service, you acknowledge that you are responsible for your actions and for ensuring that your usage of Folo is consistent with these Terms.
|
||||
|
||||
## 2. Eligibility
|
||||
You must be at least 13 years old to use Folo. By using the Service, you represent and warrant that you meet this eligibility requirement. If you are under the age of 13, you are prohibited from using the Service. Natural Selection Limited reserves the right to suspend or terminate the access of any user who violates these eligibility requirements. Additionally, if you are using Folo on behalf of a company, you confirm that you have the authority to bind the company to these Terms.
|
||||
|
||||
## 3. User Account
|
||||
To access certain features of the Service, you may be required to create an account. You are responsible for maintaining the confidentiality of your account credentials, such as your username and password, and for all activities that occur under your account. If you suspect any unauthorized access or use of your account, you must notify us immediately to avoid any potential security breaches. You agree to provide accurate, up-to-date information when creating or maintaining your account and understand that failure to do so may result in limitations to your access or functionality of the Service.
|
||||
|
||||
## 4. Permitted Use
|
||||
You agree to use Folo solely for lawful purposes and in a manner that does not violate the rights of others. You shall not use the Service for any unlawful, harmful, or malicious activities. You are prohibited from transmitting harmful content such as malware, viruses, or phishing attempts, and from interfering with the operation or security features of the Service. Unauthorized attempts to gain access to the Service through hacking, password mining, or any other unlawful means are strictly prohibited and may result in immediate termination of your account.
|
||||
|
||||
You also agree not to exploit any part of the Service, including features, tools, or content, for commercial purposes unless explicitly authorized by Natural Selection Limited.
|
||||
|
||||
## 5. Content and Intellectual Property
|
||||
|
||||
### 5.1 User Content
|
||||
Folo enables you to import, subscribe to, and read content via RSS feeds. You retain full ownership of any content you post, upload, or submit to the Service. By submitting or sharing content, you grant us a worldwide, royalty-free, and non-exclusive license to host, display, modify, and distribute your content as necessary to operate, improve, and provide the Service. You are solely responsible for ensuring that the content you share does not infringe on the intellectual property rights of any third party. You also agree to respect the rights of content creators and copyright holders.
|
||||
|
||||
### 5.2 Intellectual Property Rights
|
||||
The Service and its underlying technology, including software, designs, and content, are owned by Natural Selection Limited or its licensors. You are granted a limited, non-exclusive, non-transferable right to access and use the Service solely for personal, non-commercial purposes. You may not copy, modify, reverse-engineer, distribute, or otherwise exploit any part of the Service without explicit permission from us. All trademarks, logos, and service marks displayed on the Service are the property of Natural Selection Limited or their respective owners. Unauthorized use of any intellectual property displayed on the Service is strictly prohibited.
|
||||
|
||||
### 5.3 AI Features and Usage
|
||||
Folo incorporates AI-powered features that assist in content translation, summarization, intelligent recommendations, and more. While these features are designed to enhance your user experience, you acknowledge that the accuracy and usefulness of AI-generated content may vary. We do not guarantee the correctness, completeness, or reliability of AI outputs and disclaim all responsibility for any adverse effects resulting from their use. Use of these features is entirely at your own risk, and you agree to hold Natural Selection Limited harmless for any errors, misunderstandings, or unintended outcomes arising from the use of AI functionality.
|
||||
|
||||
### 5.4 $POWER Economy
|
||||
Folo introduces the $POWER system, a way for users to support content creators and contributors by tipping or rewarding them with $POWER. You can acquire $POWER by participating in the community, completing designated tasks, or purchasing it through the app. You agree to abide by the rules governing the $POWER system, including: (i) not engaging in fraudulent activities or exploiting the system for illegal or malicious purposes; (ii) acknowledging that $POWER cannot be exchanged for real-world currency or transferred outside of the Service; (iii) accepting that $POWER transactions are final and non-refundable.
|
||||
|
||||
Folo reserves the right to modify, suspend, or terminate the $POWER system at any time without prior notice.
|
||||
|
||||
## 6. Prohibited Activities
|
||||
You agree not to engage in any of the following activities while using the Service:
|
||||
- Engage in any illegal or harmful activities, including distributing malicious software or engaging in data breaches.
|
||||
- Attempt to gain unauthorized access to any part of the Service or its security features.
|
||||
- Misuse the $POWER system by gaming the economy or making fraudulent transactions.
|
||||
- Engage in any behavior that disrupts the normal functionality of the Service or harms other users’ experiences.
|
||||
|
||||
Violations of these activities may result in the immediate suspension or termination of your account. In some cases, legal action may be taken if necessary to protect our rights or the rights of others.
|
||||
|
||||
## 7. Disclaimer of Warranties
|
||||
The Service is provided on an "AS IS" and "AS AVAILABLE" basis. We do not make any representations or warranties regarding the availability, functionality, or reliability of the Service. We disclaim all express or implied warranties, including but not limited to warranties of merchantability, fitness for a particular purpose, and non-infringement. We do not guarantee that the Service will be uninterrupted, error-free, or free from security vulnerabilities.
|
||||
|
||||
## 8. Limitation of Liability
|
||||
To the fullest extent permitted by law, Natural Selection Limited shall not be liable for any indirect, incidental, special, or consequential damages arising from your use of the Service, including but not limited to loss of profits, data, or goodwill. In no event shall our liability exceed the total amount you have paid to access the Service during the past 12 months. You agree that your use of the Service is at your own risk.
|
||||
|
||||
## 9. Modifications to the Terms
|
||||
We reserve the right to modify these Terms at any time. Any changes will be effective immediately upon posting on the Service. We will notify you of any significant changes, but it is your responsibility to review the Terms periodically. Your continued use of the Service after any modifications will constitute your acceptance of the updated Terms. If you do not agree to the changes, you must cease using the Service and delete your account.
|
||||
|
||||
## 10. Termination
|
||||
We may suspend, disable, or terminate your access to the Service at any time, for any reason, including but not limited to violations of these Terms, fraudulent behavior, or other actions that disrupt the normal operation of the Service. Upon termination, your account will be deactivated, and you may lose access to your content and any other account-related data. If you wish to terminate your account, you can do so by contacting us or using the account settings feature within the app.
|
||||
|
||||
## 11. Governing Law
|
||||
These Terms are governed by and construed in accordance with the laws of [Insert Jurisdiction]. Any disputes arising out of or in connection with these Terms will be subject to the exclusive jurisdiction of the courts of [Insert Jurisdiction].
|
||||
|
||||
## 12. Contact Us
|
||||
If you have any questions, concerns, or inquiries about these Terms, please contact us at:
|
||||
- Email: follow@rss3.io
|
||||
|
||||
By using Folo, you acknowledge that you have read, understood, and agree to these Terms of Service, as well as our Privacy Policy.
|
||||
|
||||
## 13. Community Participation and Contribution
|
||||
Folo is an open-source project, and we welcome contributions from users and developers. If you are eligible to use Folo, you may participate in the development of the Service by submitting bug reports, feature requests, and improvements. All contributions must adhere to our [code of conduct](https://github.com/RSSNext/Folo/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
Before contributing, ensure that you have read and understood our contributing guidelines and the [Corepack](https://nodejs.org/api/corepack.html) setup instructions. By contributing, you agree that your submissions will be licensed under the terms of the [GNU General Public License](https://www.gnu.org/licenses/gpl-3.0.html) version 3.
|
||||
|
||||
## 14. Privacy and Data Use
|
||||
Folo takes your privacy seriously. As a user, you acknowledge that we may collect, store, and process your personal information, including your usage patterns and interactions with content. We are committed to ensuring that your data is handled securely and transparently. Please refer to our [Privacy Policy](#) for more information on how we collect, process, and protect your data.
|
||||
`
|
||||
|
||||
export const TermsMarkdown = () => {
|
||||
return (
|
||||
<Markdown
|
||||
value={txt}
|
||||
value={legalMarkdown.tos}
|
||||
webViewProps={{ scrollEnabled: false, matchContents: true }}
|
||||
style={{ padding: 16, flex: 1 }}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Navigation } from "./lib/navigation/Navigation"
|
|||
import { NavigationSitemapRegistry } from "./lib/navigation/sitemap/registry"
|
||||
import type { NavigationControllerView } from "./lib/navigation/types"
|
||||
import { OTPWindow } from "./modules/settings/components/OTPWindow"
|
||||
import { PrivacyPolicyScreen } from "./screens/(headless)/privacy"
|
||||
import { TermsScreen } from "./screens/(headless)/terms"
|
||||
import { ForgetPasswordScreen } from "./screens/(modal)/ForgetPasswordScreen"
|
||||
import { InvitationScreen } from "./screens/(modal)/InvitationScreen"
|
||||
|
|
@ -14,7 +15,7 @@ import { TwoFactorAuthScreen } from "./screens/(modal)/TwoFactorAuthScreen"
|
|||
import { OnboardingScreen } from "./screens/OnboardingScreen"
|
||||
|
||||
export function registerSitemap() {
|
||||
;[TermsScreen].forEach((Component) => {
|
||||
;[TermsScreen, PrivacyPolicyScreen].forEach((Component) => {
|
||||
NavigationSitemapRegistry.registerByComponent(Component)
|
||||
})
|
||||
;[LoginScreen, InvitationScreen, ForgetPasswordScreen, TwoFactorAuthScreen].forEach(
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { FetchError } from "ofetch"
|
|||
|
||||
import { isDev } from "~/lib/env"
|
||||
import { MetaError } from "~/meta-handler"
|
||||
import { staticRoute } from "~/router/static"
|
||||
|
||||
import { globalRoute } from "./src/router/global"
|
||||
import { ogRoute } from "./src/router/og"
|
||||
|
|
@ -77,6 +78,7 @@ export const createApp = async () => {
|
|||
|
||||
ogRoute(app)
|
||||
globalRoute(app)
|
||||
staticRoute(app)
|
||||
|
||||
return app
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
"@follow/configs": "workspace:*",
|
||||
"@follow/constants": "workspace:*",
|
||||
"@follow/hooks": "workspace:*",
|
||||
"@follow/legal": "workspace:*",
|
||||
"@follow/models": "workspace:*",
|
||||
"@follow/shared": "workspace:*",
|
||||
"@follow/types": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import { legalHtml } from "@follow/legal"
|
||||
import type { FastifyInstance } from "fastify"
|
||||
|
||||
export const staticRoute = (app: FastifyInstance) => {
|
||||
app.get("/privacy-policy", (req, res) => {
|
||||
res.type("text/html")
|
||||
res.send(legalHtml.privacy)
|
||||
})
|
||||
app.get("/terms", (req, res) => {
|
||||
res.type("text/html")
|
||||
res.send(legalHtml.tos)
|
||||
})
|
||||
}
|
||||
|
|
@ -224,6 +224,7 @@
|
|||
"feed_item.claimed_list": "Claimed List",
|
||||
"feed_item.error_since": "Error since",
|
||||
"feed_item.not_publicly_visible": "Not publicly visible on your profile page",
|
||||
"login.agree_to": "By continuing, you agree to our",
|
||||
"login.back": "Back",
|
||||
"login.confirm_password.label": "Confirm Password",
|
||||
"login.continueWith": "Continue with {{provider}}",
|
||||
|
|
@ -233,8 +234,10 @@
|
|||
"login.no_account": "Don't have an account? <strong>Sign up</strong>",
|
||||
"login.or": "OR",
|
||||
"login.password": "Password",
|
||||
"login.privacy": "Privacy Policy",
|
||||
"login.signUp": "Sign up with email",
|
||||
"login.submit": "Submit",
|
||||
"login.terms": "Terms of Service",
|
||||
"login.with_email.title": "Login with Email",
|
||||
"mark_all_read_button.auto_confirm_info": "Will be confirmed automatically after {{countdown}}s.",
|
||||
"mark_all_read_button.confirm": "Confirm",
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@
|
|||
"feed_item.claimed_list": "已认证列表",
|
||||
"feed_item.error_since": "源失效:",
|
||||
"feed_item.not_publicly_visible": "在个人页面上隐藏",
|
||||
"login.agree_to": "继续即表示您同意我们的",
|
||||
"login.back": "返回",
|
||||
"login.confirm_password.label": "确认密码",
|
||||
"login.continueWith": "使用 {{provider}} 继续",
|
||||
|
|
@ -231,8 +232,10 @@
|
|||
"login.no_account": "没有账户?<strong>注册</strong>",
|
||||
"login.or": "或",
|
||||
"login.password": "密码",
|
||||
"login.privacy": "隐私政策",
|
||||
"login.signUp": "使用邮件地址注册",
|
||||
"login.submit": "提交",
|
||||
"login.terms": "服务条款",
|
||||
"login.with_email.title": "使用邮件地址登录",
|
||||
"mark_all_read_button.auto_confirm_info": "{{countdown}} 秒后自动确认。",
|
||||
"mark_all_read_button.confirm": "确认",
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
"login.continueWith": "Continue with {{provider}}",
|
||||
"login.email": "Email",
|
||||
"login.errors.unknown": "Errors Unknown",
|
||||
"login.forget_password.description": "Enter the email address associated with your account and we’ll send you an email about how to reset your password.",
|
||||
"login.forget_password.description": "Enter the email address associated with your account and we'll send you an email about how to reset your password.",
|
||||
"login.forget_password.email_invalid": "Invalid email",
|
||||
"login.forget_password.email_required": "Email required",
|
||||
"login.forget_password.label": "Forget Password",
|
||||
|
|
|
|||
|
|
@ -331,6 +331,7 @@
|
|||
"lists.subscriptions": "Subs",
|
||||
"lists.title": "Title",
|
||||
"lists.view": "View",
|
||||
"privacy.privacy": "Privacy",
|
||||
"privacy.terms": "Terms",
|
||||
"profile.avatar.label": "Avatar",
|
||||
"profile.change_password.label": "Change Password",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
"type": "git"
|
||||
},
|
||||
"scripts": {
|
||||
"build:packages": "turbo run build --filter='./packages/**/*'",
|
||||
"build:web": "turbo run Folo#build:web",
|
||||
"dedupe:locales": "eslint --fix locales/**",
|
||||
"depcheck": "npx depcheck --quiet",
|
||||
|
|
@ -26,6 +27,7 @@
|
|||
"lint:tsl": "tsslint --project apps/*/tsconfig.json",
|
||||
"mitproxy": "bash scripts/run-proxy.sh",
|
||||
"polyfill-optimize": "pnpx nolyfill install",
|
||||
"postinstall": "pnpm run build:packages",
|
||||
"prepare": "simple-git-hooks && corepack prepare",
|
||||
"reinstall": "rm -rf node_modules && rm -rf apps/**/node_modules && rm -rf packages/**/node_modules && pnpm install",
|
||||
"test": "cross-env CI=1 pnpm --recursive run test",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "@follow/legal",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"exports": {
|
||||
".": "./dist/index.ts",
|
||||
"./privacy": "./dist/privacy.html",
|
||||
"./tos": "./dist/tos.html"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsx script/build.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"marked": "15.0.11"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
# Folo Privacy Policy
|
||||
|
||||
**Effective Date:** 2025-05-15
|
||||
|
||||
At Folo, your personalized RSS reader and content hub, we are committed to protecting your privacy and handling your personal data responsibly. This Privacy Policy explains how Natural Selection Limited ("we," "us," or "Folo"), the operator of Folo, collects, uses, shares, stores, and protects your personal data when you use our application and related services (collectively, the "Service"). By using Folo, you agree to the practices described in this Privacy Policy and our [Terms of Service](https://app.follow.is/terms).
|
||||
|
||||
This policy is designed to comply with Singapore’s Personal Data Protection Act (PDPA) and, where applicable, other data protection laws such as the European Union’s General Data Protection Regulation (GDPR) and the California Consumer Privacy Act (CCPA). If you have any questions, please contact us at follow@rss3.io.
|
||||
|
||||
## 1. What Data We Collect
|
||||
|
||||
We collect personal data to provide, improve, and personalize the Service. The types of data we collect include:
|
||||
|
||||
### 1.1 Information You Provide
|
||||
|
||||
- **Account Information**: When you create a Folo account, we collect your email address, username, and password. You may optionally provide additional details, such as your name or profile preferences.
|
||||
- **User Content**: Data you submit, such as RSS feed subscriptions, comments, or content you upload or share via the Service.
|
||||
- **$POWER Transactions**: If you purchase or earn $POWER (our virtual point system), we collect payment-related information (e.g., transaction IDs) and details of your $POWER activities.
|
||||
- **Communications**: Information you provide when contacting us (e.g., via follow@rss3.io or in-app support), such as your name, email, and message content.
|
||||
|
||||
### 1.2 Information We Collect Automatically
|
||||
|
||||
- **Usage Data**: Information about how you interact with the Service, including pages visited, features used (e.g., AI-powered translation or recommendations), RSS feeds subscribed, and $POWER transactions.
|
||||
- **Device and Technical Data**: IP address, device type, operating system, browser type, and unique device identifiers.
|
||||
- **Analytics Data**: Aggregated data on user behavior, such as time spent on the app or frequency of feature use, collected via analytics tools.
|
||||
|
||||
### 1.3 Information from Third Parties
|
||||
|
||||
- **Third-Party RSS Feeds**: Content from RSS feeds you subscribe to, which may include metadata (e.g., article titles, publication dates) but not personal data unless you explicitly share it.
|
||||
- **Payment Processors**: If you purchase $POWER, our third-party payment processors collect payment details (e.g., credit card information), which we do not store directly.
|
||||
|
||||
We do not collect sensitive personal data (e.g., health, biometric, or racial information) unless voluntarily provided by you in user content, and we discourage sharing such data.
|
||||
|
||||
## 2. How We Use Your Data
|
||||
|
||||
We use your data to provide, improve, and personalize the Service. Specific purposes include:
|
||||
|
||||
- **Service Delivery**: To manage your account, process $POWER transactions, display RSS feeds, and enable features like AI-powered translation, summarization, and recommendations.
|
||||
- **Personalization**: To tailor content and recommendations based on your subscriptions and usage patterns.
|
||||
- **Analytics and Improvement**: To analyze usage trends, troubleshoot issues, and enhance the Service’s functionality and user experience.
|
||||
- **Security**: To detect and prevent fraud, unauthorized access, or malicious activities (e.g., misuse of the $POWER system).
|
||||
- **Communication**: To respond to your inquiries, send service-related notifications (e.g., Terms of Service updates), and, with your consent, provide promotional updates.
|
||||
- **Legal Compliance**: To comply with applicable laws, regulations, or legal requests (e.g., under Singapore’s PDPA).
|
||||
|
||||
## 3. How We Share Your Data
|
||||
|
||||
We do not sell your personal data. We may share your data in the following circumstances:
|
||||
|
||||
- **Service Providers**: With trusted third-party providers who assist with hosting, analytics, payment processing, or customer support. These providers are contractually obligated to protect your data and use it only for the services they provide to us.
|
||||
- **$POWER System**: Limited data (e.g., usernames) may be shared with content creators you reward with $POWER to facilitate recognition within the Service.
|
||||
- **Legal Obligations**: When required by law, court order, or government authority (e.g., to comply with PDPA or respond to lawful requests).
|
||||
- **Business Transfers**: In the event of a merger, acquisition, or sale of assets, your data may be transferred to a successor entity, subject to equivalent privacy protections.
|
||||
- **With Your Consent**: If you explicitly agree to data sharing (e.g., for third-party integrations you authorize).
|
||||
|
||||
User content you share publicly (e.g., comments visible to other users) is your responsibility, and you should avoid sharing sensitive information.
|
||||
|
||||
## 4. Your Rights and Choices
|
||||
|
||||
You have rights over your personal data, subject to applicable laws (e.g., PDPA, GDPR, CCPA). These include:
|
||||
|
||||
- **Access**: Request a copy of the personal data we hold about you.
|
||||
- **Correction**: Request correction of inaccurate or incomplete data.
|
||||
- **Deletion**: Request deletion of your data, subject to legal retention requirements.
|
||||
- **Data Portability**: Request a copy of your data (e.g., RSS subscriptions) in a structured, machine-readable format.
|
||||
- **Objection/Restriction**: Object to or restrict certain data processing activities (e.g., personalized recommendations).
|
||||
- **Withdraw Consent**: Where we rely on your consent (e.g., for promotional emails), you may withdraw it at any time.
|
||||
|
||||
To exercise these rights, contact us at follow@rss3.io or use the in-app support feature. We will respond within 30 days, as required by PDPA, or sooner if mandated by other laws (e.g., GDPR’s 1-month timeline).
|
||||
|
||||
You may also:
|
||||
|
||||
- **Manage Notifications**: Opt out of non-essential communications via account settings or by following unsubscribe instructions in emails.
|
||||
- **Disable Analytics**: Adjust device settings or contact us to limit analytics tracking, where feasible.
|
||||
- **Delete Your Account**: Terminate your account via account settings, which will delete associated personal data, except where retention is legally required.
|
||||
|
||||
## 5. Data Retention
|
||||
|
||||
We retain your personal data only as long as necessary for the purposes outlined in this policy or as required by law:
|
||||
|
||||
- **Account Data**: Retained while your account is active and for [6 months] after account deletion to address disputes or legal requirements, unless a longer period is mandated.
|
||||
- **Usage Data**: Retained in aggregated, anonymized form for analytics purposes.
|
||||
- **$POWER Transactions**: Retained for [5 years] to comply with financial record-keeping laws.
|
||||
- **User Content**: Retained until you request deletion or your account is terminated, subject to legal obligations.
|
||||
|
||||
After the retention period, we will securely delete or anonymize your data. Contact us for specific retention details.
|
||||
|
||||
## 6. Data Security
|
||||
|
||||
We implement reasonable technical and organizational measures to protect your data, including:
|
||||
|
||||
- Encryption of data in transit (e.g., via HTTPS) and at rest where feasible.
|
||||
- Access controls to limit data access to authorized personnel.
|
||||
- Regular security assessments to identify and address vulnerabilities.
|
||||
|
||||
However, no system is completely secure. If we detect a data breach, we will notify affected users and relevant authorities (e.g., Singapore’s Personal Data Protection Commission) as required by law (e.g., within 72 hours under PDPA).
|
||||
|
||||
## 7. International Data Transfers
|
||||
|
||||
Folo is operated from Singapore, but our service providers may be located in other countries. When we transfer your data outside Singapore, we ensure appropriate safeguards, such as:
|
||||
|
||||
- Standard Contractual Clauses (SCCs) for transfers to jurisdictions without adequate data protection (e.g., under GDPR).
|
||||
- Compliance with PDPA’s requirements for overseas data transfers.
|
||||
|
||||
If you are in the EU or another region with strict data protection laws, contact us for details on our transfer mechanisms.
|
||||
|
||||
## 8. Children’s Privacy
|
||||
|
||||
Folo is not intended for users under 13. We do not knowingly collect personal data from children under 13. If we learn such data has been collected, we will promptly delete it. If you believe a child under 13 has provided data, contact us at follow@rss3.io.
|
||||
|
||||
## 9. Third-Party Links and Services
|
||||
|
||||
The Service includes third-party RSS feeds and may link to external sites. We are not responsible for the privacy practices of these third parties. Review their privacy policies before sharing data. Similarly, our payment processors handle payment data under their own policies, which you should review.
|
||||
|
||||
## 10. AI Features and Data Use
|
||||
|
||||
Folo’s AI features (e.g., translation, summarization) may process your RSS feed data and usage patterns to generate outputs. We do not use your personal data to train AI models without your explicit consent. AI-generated outputs are provided “as is,” and you should verify their accuracy.
|
||||
|
||||
## 11. $POWER System
|
||||
|
||||
When you use $POWER, we collect transaction data to facilitate rewards and prevent fraud. We do not share payment details beyond what is necessary for processing. $POWER has no real-world monetary value, and related data is retained as outlined in Section 5.
|
||||
|
||||
## 12. Updates to This Privacy Policy
|
||||
|
||||
We may update this Privacy Policy to reflect changes in our practices or legal requirements. We will notify you of significant changes (e.g., new data uses) at least 14 days in advance via email, in-app notification, or our website (https://app.follow.is). Continued use of the Service after updates constitutes acceptance. Check this page periodically for the latest version.
|
||||
|
||||
## 13. Contact Us
|
||||
|
||||
For questions, concerns, or to exercise your data rights, contact us at:
|
||||
|
||||
- **Email**: follow@rss3.io
|
||||
|
||||
If you are in Singapore and believe we have not addressed your concerns, you may contact the Personal Data Protection Commission (PDPC) at https://www.pdpc.gov.sg/.
|
||||
|
||||
If you are in the EU, you may contact your local data protection authority. Our EU representative (if required under GDPR) can be reached at [Insert EU Representative Contact, if applicable].
|
||||
|
||||
## 14. Additional Information for Specific Jurisdictions
|
||||
|
||||
- **EU/EEA Users (GDPR)**: We process10 apply GDPR safeguards for data transfers and designate an EU representative if required. You have rights to access, rectify, erase, restrict, or port your data.
|
||||
- **California Users (CCPA)**: You have rights to know, delete, and opt out of data sales (we do not sell data). Contact us to exercise these rights.
|
||||
- **Singapore Users (PDPA)**: We comply with PDPA’s requirements for consent, notification, and data protection.
|
||||
|
||||
By using Folo, you acknowledge that you have read and understood this Privacy Policy.
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
import { mkdirSync, readFileSync, writeFileSync } from "node:fs"
|
||||
import { resolve } from "node:path"
|
||||
|
||||
import { marked } from "marked"
|
||||
|
||||
// Define paths to markdown and output files
|
||||
const PRIVACY_MD_PATH = resolve(__dirname, "../privacy.md")
|
||||
const TOS_MD_PATH = resolve(__dirname, "../tos.md")
|
||||
const OUTPUT_PATH = resolve(__dirname, "../dist")
|
||||
|
||||
// GitHub markdown CSS style
|
||||
const githubMarkdownCSS = `
|
||||
<style>
|
||||
.markdown-body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
padding: 45px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.markdown-body h1, .markdown-body h2, .markdown-body h3,
|
||||
.markdown-body h4, .markdown-body h5, .markdown-body h6 {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
}
|
||||
.markdown-body h1 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 2em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
.markdown-body h2 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 1.5em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
.markdown-body p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.markdown-body ul, .markdown-body ol {
|
||||
padding-left: 2em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.markdown-body code {
|
||||
padding: 0.2em 0.4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(27,31,35,0.05);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.markdown-body blockquote {
|
||||
padding: 0 1em;
|
||||
color: #6a737d;
|
||||
border-left: 0.25em solid #dfe2e5;
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
</style>
|
||||
`
|
||||
|
||||
/**
|
||||
* Converts markdown content to HTML with GitHub styling
|
||||
*/
|
||||
function convertMarkdownToHtml(markdown: string): string {
|
||||
const htmlContent = marked(markdown)
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
${githubMarkdownCSS}
|
||||
</head>
|
||||
<body>
|
||||
<div class="markdown-body">
|
||||
${htmlContent}
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
}
|
||||
|
||||
// Main build function
|
||||
async function build() {
|
||||
try {
|
||||
mkdirSync(OUTPUT_PATH, { recursive: true })
|
||||
// Create output objects
|
||||
const output: Record<string, string> = {}
|
||||
|
||||
// Read and convert markdown files
|
||||
const privacyMd = readFileSync(PRIVACY_MD_PATH, "utf-8")
|
||||
const tosMd = readFileSync(TOS_MD_PATH, "utf-8")
|
||||
|
||||
// Convert markdown to HTML
|
||||
const privacyHtml = convertMarkdownToHtml(privacyMd)
|
||||
const tosHtml = convertMarkdownToHtml(tosMd)
|
||||
|
||||
// Add to output object
|
||||
output.privacy = privacyHtml
|
||||
output.tos = tosHtml
|
||||
|
||||
// Create output directory and write files
|
||||
try {
|
||||
// Write the HTML files for reference
|
||||
writeFileSync(`${OUTPUT_PATH}/privacy.html`, privacyHtml)
|
||||
writeFileSync(`${OUTPUT_PATH}/tos.html`, tosHtml)
|
||||
|
||||
// Export as a module
|
||||
const moduleContent = `export const legalHtml = ${JSON.stringify(output, null, 2)}; export const legalMarkdown = ${JSON.stringify(
|
||||
{
|
||||
privacy: privacyMd,
|
||||
tos: tosMd,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)};`
|
||||
writeFileSync(`${OUTPUT_PATH}/index.ts`, moduleContent)
|
||||
|
||||
console.info("✅ Legal documents successfully built")
|
||||
} catch (error) {
|
||||
console.error("Failed to write output files:", error)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Build failed:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// Run the build
|
||||
build().catch(console.error)
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
# Terms of Service
|
||||
|
||||
**Effective Date:** 2025-05-15
|
||||
|
||||
Welcome to Folo, your personalized RSS reader and content hub. By using our application, you agree to these Terms of Service ("Terms"). Please read them carefully as they govern your use of the Service and the rights and obligations that come with it.
|
||||
|
||||
Folo is designed to provide an intuitive, efficient, and user-friendly experience in managing your RSS feeds. We aim to offer a seamless and secure environment, but it’s important for you to understand your rights and responsibilities while using the Service.
|
||||
|
||||
## Definitions
|
||||
|
||||
- **Service**: The Folo application and its related features, including the RSS reader, AI-powered functionalities, and $POWER system.
|
||||
- **User Content**: Any data, materials, or information you upload, submit, or share through the Service.
|
||||
- **$POWER**: A virtual point system within the Service used to reward content creators, with no real-world monetary value.
|
||||
|
||||
## 1. Acceptance of Terms
|
||||
|
||||
By accessing or using Folo ("the Service"), you agree to comply with and be bound by these Terms and our Privacy Policy. If you do not agree to these Terms, you may not use the Service. These Terms form a legally binding contract between you and Natural Selection Limited, which owns and operates Folo. You are responsible for your actions and for ensuring your use of the Service complies with these Terms.
|
||||
|
||||
## 2. Eligibility
|
||||
|
||||
You must be at least 13 years old to use Folo. By using the Service, you represent and warrant that you meet this eligibility requirement. If you are under 13, you are prohibited from using the Service. Natural Selection Limited reserves the right to suspend or terminate access for users who violate these requirements. If you use Folo on behalf of a company, you confirm you have the authority to bind the company to these Terms.
|
||||
|
||||
## 3. User Account
|
||||
|
||||
To access certain features, you may need to create an account. You are responsible for maintaining the confidentiality of your account credentials (e.g., username and password) and for all activities under your account. Notify us immediately at follow@rss3.io if you suspect unauthorized access. You agree to provide accurate, up-to-date information when creating or maintaining your account. Failure to do so may result in limited access or functionality.
|
||||
|
||||
## 4. Permitted Use
|
||||
|
||||
You agree to use Folo solely for lawful purposes and in a manner that respects the rights of others. You shall not use the Service for unlawful, harmful, or malicious activities, including transmitting malware, viruses, or phishing attempts, or interfering with the Service’s operation or security. Unauthorized attempts to access the Service through hacking or other unlawful means are prohibited and may result in account termination.
|
||||
|
||||
You may not exploit the Service for commercial purposes unless explicitly authorized by Natural Selection Limited.
|
||||
|
||||
## 5. Service Fees
|
||||
|
||||
Folo offers both free and paid features. Certain functionalities, such as advanced AI features or additional $POWER purchases, may require payment. All fees will be clearly disclosed in the application or on our website (https://app.follow.is). Fees are non-refundable unless required by applicable law.
|
||||
|
||||
## 6. Content and Intellectual Property
|
||||
|
||||
### 6.1 User Content
|
||||
|
||||
Folo enables you to import, subscribe to, and read content via RSS feeds. You retain ownership of any content you post, upload, or submit. By sharing content, you grant us a worldwide, royalty-free, non-exclusive license to host, display, modify, and distribute your content as necessary to operate, improve, and provide the Service. You are responsible for ensuring your content does not infringe third-party intellectual property rights and for respecting the rights of content creators and copyright holders.
|
||||
|
||||
### 6.2 Intellectual Property Rights
|
||||
|
||||
The Service, including its software, designs, and content, is owned by Natural Selection Limited or its licensors. You are granted a limited, non-exclusive, non-transferable right to use the Service for personal, non-commercial purposes. You may not copy, modify, reverse-engineer, or distribute any part of the Service without our permission. All trademarks, logos, and service marks are the property of Natural Selection Limited or their respective owners. Unauthorized use is prohibited.
|
||||
|
||||
### 6.3 AI Features and Usage
|
||||
|
||||
Folo incorporates AI-powered features for content translation, summarization, and recommendations. We strive to ensure these features provide useful outputs, but we do not guarantee their accuracy, completeness, or reliability. You should independently verify AI-generated content, especially for critical decisions. Natural Selection Limited is not liable for losses or damages from relying on AI content, except where caused by our gross negligence. Report significant AI errors to follow@rss3.io for us to improve the Service.
|
||||
|
||||
### 6.4 $POWER Economy
|
||||
|
||||
Folo’s $POWER system allows users to support content creators by tipping or rewarding with $POWER, a virtual point system with no real-world monetary value. You can acquire $POWER through community participation, tasks, or in-app purchases. You agree to:
|
||||
|
||||
- Not engage in fraudulent or malicious activities with $POWER.
|
||||
- Acknowledge $POWER cannot be exchanged for currency or transferred outside the Service.
|
||||
- Accept that $POWER transactions are final and non-refundable.
|
||||
- Comply with any tax or legal obligations related to $POWER purchases.
|
||||
|
||||
If you have disputes about $POWER transactions, contact us at follow@rss3.io. We will investigate and respond within 30 days, but our decision is final. If we terminate the $POWER system, we will notify users at least 30 days in advance via email or in-app notification. Unused $POWER will expire upon termination without refund or compensation.
|
||||
|
||||
We reserve the right to modify, suspend, or terminate the $POWER system at any time with notice.
|
||||
|
||||
## 7. Prohibited Activities
|
||||
|
||||
You agree not to:
|
||||
|
||||
- Engage in illegal or harmful activities, such as distributing malicious software or breaching data.
|
||||
- Attempt unauthorized access to the Service or its security features.
|
||||
- Misuse the $POWER system through fraudulent transactions.
|
||||
- Disrupt the Service’s functionality or harm other users’ experiences.
|
||||
|
||||
Violations may result in account suspension or termination and, if necessary, legal action.
|
||||
|
||||
## 8. Disclaimer of Warranties
|
||||
|
||||
The Service is provided “AS IS” and “AS AVAILABLE.” We do not guarantee uninterrupted, error-free, or secure operation. We disclaim all express or implied warranties, including merchantability, fitness for a particular purpose, and non-infringement, to the fullest extent permitted by law.
|
||||
|
||||
## 9. Limitation of Liability
|
||||
|
||||
To the fullest extent permitted by law, except where caused by our gross negligence or willful misconduct, Natural Selection Limited is not liable for indirect, incidental, special, or consequential damages, including loss of profits, data, or goodwill. Our total liability shall not exceed the greater of the amount you paid for the Service in the past 12 months or SGD 100. These Terms do not limit statutory rights that cannot be waived by contract under applicable law.
|
||||
|
||||
## 10. Modifications to the Terms
|
||||
|
||||
We may modify these Terms at any time. Changes take effect upon posting to the Service. For significant changes (e.g., affecting user rights, fees, or data use), we will notify you at least 14 days in advance via email, in-app notification, or our website (https://app.follow.is). If you disagree with the changes, you may terminate your account before they take effect by contacting us or using account settings. Continued use after changes constitutes acceptance. You are responsible for periodically reviewing the Terms.
|
||||
|
||||
## 11. Termination
|
||||
|
||||
We may suspend, disable, or terminate your access to the Service at any time for reasons including violations of these Terms or fraudulent behavior. Except for immediate termination due to legal or policy violations, we will notify you 14 days in advance via email or in-app notification. You may export your RSS subscriptions and other user-generated content (if applicable) via the account settings’ export feature before termination. We recommend regular backups. Upon termination, your account will be deactivated, and we do not guarantee retention of your data unless required by law.
|
||||
|
||||
To terminate your account, use the account settings or contact us at follow@rss3.io.
|
||||
|
||||
## 12. Governing Law
|
||||
|
||||
These Terms are governed by and construed in accordance with the laws of the Republic of Singapore. Any disputes arising out of or in connection with these Terms will be subject to the exclusive jurisdiction of the courts of Singapore.
|
||||
|
||||
## 13. Contact Us
|
||||
|
||||
For questions, concerns, or support, contact us at:
|
||||
|
||||
- **Email**: follow@rss3.io
|
||||
|
||||
## 14. Community Participation and Contribution
|
||||
|
||||
Folo is an open-source project, and we welcome contributions such as bug reports, feature requests, and improvements. Contributions must adhere to our [Code of Conduct](https://github.com/RSSNext/Folo/blob/main/CODE_OF_CONDUCT.md) and contributing guidelines, including [Corepack](https://nodejs.org/api/corepack.html) setup. By contributing, you agree your submissions are licensed under the [GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
|
||||
## 15. Privacy and Data Use
|
||||
|
||||
Folo takes your privacy seriously. We may collect, store, and process personal information, including usage patterns and content interactions. Our [Privacy Policy](https://app.follow.is/privacy-policy) (available soon) will detail how we collect, process, and protect your data. Until available, contact follow@rss3.io for privacy inquiries. We are committed to handling your data securely and transparently in compliance with applicable laws, including Singapore’s Personal Data Protection Act.
|
||||
|
|
@ -215,6 +215,9 @@ importers:
|
|||
'@follow/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/hooks
|
||||
'@follow/legal':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/legal
|
||||
'@follow/models':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/models
|
||||
|
|
@ -766,6 +769,9 @@ importers:
|
|||
'@follow/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/hooks
|
||||
'@follow/legal':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/legal
|
||||
'@follow/models':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/models
|
||||
|
|
@ -1223,6 +1229,9 @@ importers:
|
|||
'@follow/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/hooks
|
||||
'@follow/legal':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/legal
|
||||
'@follow/models':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/models
|
||||
|
|
@ -1587,6 +1596,12 @@ importers:
|
|||
specifier: workspace:*
|
||||
version: link:../../configs
|
||||
|
||||
packages/internal/legal:
|
||||
devDependencies:
|
||||
marked:
|
||||
specifier: 15.0.11
|
||||
version: 15.0.11
|
||||
|
||||
packages/internal/logger:
|
||||
dependencies:
|
||||
electron-log:
|
||||
|
|
@ -11320,6 +11335,11 @@ packages:
|
|||
markdown-table@3.0.4:
|
||||
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
|
||||
|
||||
marked@15.0.11:
|
||||
resolution: {integrity: sha512-1BEXAU2euRCG3xwgLVT1y0xbJEld1XOrmRJpUwRCcy7rxhSCwMrmEu9LXoPhHSCJG41V7YcQ2mjKRr5BA3ITIA==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
|
||||
marky@1.3.0:
|
||||
resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==}
|
||||
|
||||
|
|
@ -27461,6 +27481,8 @@ snapshots:
|
|||
|
||||
markdown-table@3.0.4: {}
|
||||
|
||||
marked@15.0.11: {}
|
||||
|
||||
marky@1.3.0: {}
|
||||
|
||||
masonic@4.1.0(react@19.0.0):
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"envMode": "loose",
|
||||
"tasks": {
|
||||
"Folo#build:web": {
|
||||
"dependsOn": ["@follow/legal#build"],
|
||||
"outputs": ["out/**"]
|
||||
},
|
||||
"//#format:check": {},
|
||||
|
|
@ -15,6 +16,10 @@
|
|||
"dependsOn": ["@follow/electron-main#build"]
|
||||
},
|
||||
"@follow/ssr#build": {
|
||||
"dependsOn": ["@follow/legal#build"],
|
||||
"outputs": ["dist/**"]
|
||||
},
|
||||
"build": {
|
||||
"outputs": ["dist/**"]
|
||||
},
|
||||
"dev": {
|
||||
|
|
|
|||
20
vercel.json
20
vercel.json
|
|
@ -69,6 +69,26 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/terms",
|
||||
"destination": "https://follow-external-ssr.vercel.app/terms",
|
||||
"has": [
|
||||
{
|
||||
"type": "host",
|
||||
"value": "app.follow.is"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/privacy-policy",
|
||||
"destination": "https://follow-external-ssr.vercel.app/privacy-policy",
|
||||
"has": [
|
||||
{
|
||||
"type": "host",
|
||||
"value": "app.follow.is"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/external-dist/:path*",
|
||||
"destination": "https://follow-external-ssr.vercel.app/external-dist/:path*",
|
||||
|
|
|
|||
Loading…
Reference in New Issue