Skip to content

Commit

Permalink
feat: add agreement about collect privacy has changed
Browse files Browse the repository at this point in the history
  • Loading branch information
hqer927 committed Sep 9, 2024
1 parent 55ff48e commit 5ba68ec
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/deploy-web-dev-cn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ jobs:
cache: "pnpm"

- name: Install dependencies
env:
FLAT_AGREEMENT_URL: ${{ vars.FLAT_AGREEMENT_URL }}
run: |
echo "FLAT_AGREEMENT_URL=$FLAT_AGREEMENT_URL" >> config/CN/.env.development
node ./scripts/ci/remove-workspace-packages.js web
node ./scripts/ci/remove-package-scripts-hooks.js
# failure automatically retries 3 times
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/deploy-web-prod-cn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ jobs:
version: latest

- name: Install dependencies
env:
FLAT_AGREEMENT_URL: ${{ vars.FLAT_AGREEMENT_URL }}
run: |
echo "FLAT_AGREEMENT_URL=$FLAT_AGREEMENT_URL" >> config/CN/.env.production
node ./scripts/ci/remove-workspace-packages.js web
node ./scripts/ci/remove-package-scripts-hooks.js
# failure automatically retries 3 times
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { LoginAccount, PasswordLoginType, defaultCountryCode } from "../LoginAcc
import { LoginSendCode } from "../LoginSendCode";
import { phoneValidator } from "../LoginWithPassword/validators";
import { codeValidator } from "./validators";
import { FLAT_AGREEMENT_URL } from "@netless/flat-server-api/src/constants";
export * from "../LoginButtons";
export * from "./validators";

Expand Down Expand Up @@ -197,7 +198,15 @@ export const LoginWithCode: React.FC<LoginWithCodeProps> = ({
checked={agreed}
privacyURL={privacyURL}
serviceURL={serviceURL}
onChange={setAgreed}
onChange={checked => {
if (checked) {
requestAgreement({ t, privacyURL, serviceURL }).then(agreed => {
setAgreed(agreed);
});
} else {
setAgreed(false);
}
}}
/>
<Button
className="login-big-button"
Expand All @@ -223,12 +232,65 @@ export interface RequestAgreementParams {
serviceURL?: string;
t: FlatI18nTFunction;
}

export function requestAgreement({
export interface PrivacyAgreementData {
title: string;
content: string;
}
export async function getPrivacy(props: {
privacyURL: string;
serviceURL: string;
}): Promise<PrivacyAgreementData | undefined> {
const { privacyURL, serviceURL } = props;
if (FLAT_AGREEMENT_URL) {
const data = await fetch(FLAT_AGREEMENT_URL).then(response => {
return response.json();
});
if (data.content) {
data.content = data.content
.replace(/{{serviceURL}}/g, serviceURL)
.replace(/{{privacyURL}}/g, privacyURL);
}
return data;
}
return undefined;
}
export async function requestAgreement({
t,
privacyURL,
serviceURL,
}: RequestAgreementParams): Promise<boolean> {
if (privacyURL && serviceURL) {
const data = await getPrivacy({ privacyURL, serviceURL });
if (data) {
return await new Promise<boolean>(resolve => {
Modal.confirm({
title: (
<div
style={{
borderBottom: "1px solid #EEEEEE",
textAlign: "center",
lineHeight: "30px",
}}
>
{data.title}
</div>
),
icon: null,
content: (
<div
dangerouslySetInnerHTML={{
__html: data.content,
}}
></div>
),
okText: t("cross-region-auth.agree"),
cancelText: t("cross-region-auth.disagree"),
onOk: () => resolve(true),
onCancel: () => resolve(false),
});
});
}
}
return new Promise<boolean>(resolve =>
Modal.confirm({
content: (
Expand All @@ -243,6 +305,7 @@ export function requestAgreement({
</a>
</div>
),
icon: null,
onOk: () => resolve(true),
onCancel: () => resolve(false),
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,15 @@ export const LoginWithPassword: React.FC<LoginWithPasswordProps> = ({
checked={agreed}
privacyURL={privacyURL}
serviceURL={serviceURL}
onChange={setAgreed}
onChange={checked => {
if (checked) {
requestAgreement({ t, privacyURL, serviceURL }).then(agreed => {
setAgreed(agreed);
});
} else {
setAgreed(false);
}
}}
/>

<Button
Expand Down
10 changes: 9 additions & 1 deletion packages/flat-components/src/components/RegisterModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,15 @@ export const RegisterModal: React.FC<RegisterProps> = ({
checked={agreed}
privacyURL={privacyURL}
serviceURL={serviceURL}
onChange={setAgreed}
onChange={checked => {
if (checked) {
requestAgreement({ t, privacyURL, serviceURL }).then(agreed => {
setAgreed(agreed);
});
} else {
setAgreed(false);
}
}}
/>

<Button
Expand Down
5 changes: 4 additions & 1 deletion packages/flat-i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -774,5 +774,8 @@
"privacyPolicy": "Privacy Policy",
"agree": "agree",
"disagree": "disagree"
}
},
"collect-media-options": "Audio and video data acquisition",
"collect-media-turn-on": "Turn on",
"collect-media-turn-off": "Turn off"
}
7 changes: 5 additions & 2 deletions packages/flat-i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,10 @@
"desc":"请注意,您正在加入 Agora Flat 海外版用户创建的房间。我们将严格遵守适用的法律法规要求进行数据出境安全评估,采用合理的物理隔离和安全防护措施,确保您的数据仅在您的授权许可下使用。具体内容参见{{serviceAgreement}}与{{privacyPolicy}}",
"serviceAgreement": "服务协议",
"privacyPolicy": "隐私政策",
"agree": "确定",
"agree": "同意",
"disagree": "取消"
}
},
"collect-media-options": "音视频数据采集",
"collect-media-turn-on": "开启",
"collect-media-turn-off": "关闭"
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import {
LoginPlatform,
deleteAccount,
deleteAccountValidate,
getCollectionAgreement,
loginCheck,
removeBinding,
rename,
setCollectionAgreement,
} from "@netless/flat-server-api";

import { PreferencesStoreContext, GlobalStoreContext } from "../../components/StoreProvider";
Expand All @@ -43,12 +45,45 @@ import { BindGitHub } from "./binding/GitHub";
import { BindGoogle } from "./binding/Google";
import { BindingField } from "./BindingField";
import { useBindingList } from "./binding";
import { Region } from "../../utils/join-room-handler";

enum SelectLanguage {
Chinese,
English,
}

// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const CollectionAgreement = () => {
const [isAgree, setAgree] = useState(true);
const t = useTranslate();
const sp = useSafePromise();
useEffect(() => {
sp(getCollectionAgreement()).then(res => {
setAgree(res.isAgree);
});
}, [sp]);
async function changeCollectMediaState(event: CheckboxChangeEvent): Promise<void> {
const isAgree = Boolean(event.target.value);
await sp(setCollectionAgreement(isAgree));
setAgree(isAgree);
}
return (
<div className="general-setting-item">
<div className="general-setting-item-title">{t("collect-media-options")}</div>
<div className="join-room-settings">
<Radio.Group value={isAgree} onChange={changeCollectMediaState}>
<Radio value={true}>
<span className="radio-item-inner">{t("collect-media-turn-on")}</span>
</Radio>
<Radio value={false}>
<span className="radio-item-inner">{t("collect-media-turn-off")}</span>
</Radio>
</Radio.Group>
</div>
</div>
);
};

export const GeneralSettingPage = observer(function GeneralSettingPage() {
const globalStore = useContext(GlobalStoreContext);
const preferencesStore = useContext(PreferencesStoreContext);
Expand All @@ -73,7 +108,10 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
() => `${FLAT_WEB_BASE_URL}/join/${globalStore.pmi}`,
[globalStore.pmi],
);

const serverRegion = useMemo(
() => globalStore.serverRegionConfig?.server.region,
[globalStore.serverRegionConfig?.server.region],
);
const loginButtons = useMemo(
() => process.env.LOGIN_METHODS.split(",") as LoginButtonProviderType[],
[],
Expand Down Expand Up @@ -107,7 +145,6 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
throw error;
}
}

function changeLanguage(event: CheckboxChangeEvent): void {
const language: SelectLanguage = event.target.value;
void FlatI18n.changeLanguage(language === SelectLanguage.Chinese ? "zh-CN" : "en");
Expand Down Expand Up @@ -403,6 +440,13 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
</div>
</div>
<hr />
{serverRegion === Region.CN_HZ && (
<>
<CollectionAgreement />
<hr />
</>
)}

<div className="general-setting-item">
<span className="general-setting-item-title">{t("delete-account")}</span>

Expand Down
1 change: 1 addition & 0 deletions packages/flat-server-api/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const FLAT_REGION = process.env.FLAT_REGION;
export const SERVER_DOMAINS = process.env.FLAT_SERVER_DOMAINS as unknown as Record<string, string>;

export const CURRENT_SERVER_DOMAIN = process.env.FLAT_SERVER_DOMAIN;
export const FLAT_AGREEMENT_URL = process.env.FLAT_AGREEMENT_URL;

export const COOKIE_DOMAIN = CURRENT_SERVER_DOMAIN
? CURRENT_SERVER_DOMAIN.slice(CURRENT_SERVER_DOMAIN.indexOf(".") + 1)
Expand Down
21 changes: 21 additions & 0 deletions packages/flat-server-api/src/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,27 @@ export interface RemoveBindingResult {
token: string;
}

export interface SetCollectionAgreementReq {
is_agree_collect_data: boolean;
}
export interface SetCollectionAgreementResult {
userUUID: string;
}
export interface GetCollectionAgreementResult {
isAgree: boolean;
}
export async function getCollectionAgreement(): Promise<GetCollectionAgreementResult> {
return await post<{}, GetCollectionAgreementResult>("user/agreement/get", {});
}
export async function setCollectionAgreement(
isAgree: boolean,
): Promise<SetCollectionAgreementResult> {
return await post<SetCollectionAgreementReq, SetCollectionAgreementResult>(
"user/agreement/set",
{ is_agree_collect_data: isAgree },
);
}

export async function removeBinding(target: LoginPlatform): Promise<RemoveBindingResult> {
return await post<RemoveBindingPayload, RemoveBindingResult>("user/binding/remove", {
target,
Expand Down

0 comments on commit 5ba68ec

Please sign in to comment.