Skip to content

Commit 5ba68ec

Browse files
committed
feat: add agreement about collect privacy has changed
1 parent 55ff48e commit 5ba68ec

File tree

10 files changed

+167
-10
lines changed

10 files changed

+167
-10
lines changed

.github/workflows/deploy-web-dev-cn.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ jobs:
2929
cache: "pnpm"
3030

3131
- name: Install dependencies
32+
env:
33+
FLAT_AGREEMENT_URL: ${{ vars.FLAT_AGREEMENT_URL }}
3234
run: |
35+
echo "FLAT_AGREEMENT_URL=$FLAT_AGREEMENT_URL" >> config/CN/.env.development
3336
node ./scripts/ci/remove-workspace-packages.js web
3437
node ./scripts/ci/remove-package-scripts-hooks.js
3538
# failure automatically retries 3 times

.github/workflows/deploy-web-prod-cn.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ jobs:
2323
version: latest
2424

2525
- name: Install dependencies
26+
env:
27+
FLAT_AGREEMENT_URL: ${{ vars.FLAT_AGREEMENT_URL }}
2628
run: |
29+
echo "FLAT_AGREEMENT_URL=$FLAT_AGREEMENT_URL" >> config/CN/.env.production
2730
node ./scripts/ci/remove-workspace-packages.js web
2831
node ./scripts/ci/remove-package-scripts-hooks.js
2932
# failure automatically retries 3 times

packages/flat-components/src/components/LoginPage/LoginWithCode/index.tsx

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { LoginAccount, PasswordLoginType, defaultCountryCode } from "../LoginAcc
1414
import { LoginSendCode } from "../LoginSendCode";
1515
import { phoneValidator } from "../LoginWithPassword/validators";
1616
import { codeValidator } from "./validators";
17+
import { FLAT_AGREEMENT_URL } from "@netless/flat-server-api/src/constants";
1718
export * from "../LoginButtons";
1819
export * from "./validators";
1920

@@ -197,7 +198,15 @@ export const LoginWithCode: React.FC<LoginWithCodeProps> = ({
197198
checked={agreed}
198199
privacyURL={privacyURL}
199200
serviceURL={serviceURL}
200-
onChange={setAgreed}
201+
onChange={checked => {
202+
if (checked) {
203+
requestAgreement({ t, privacyURL, serviceURL }).then(agreed => {
204+
setAgreed(agreed);
205+
});
206+
} else {
207+
setAgreed(false);
208+
}
209+
}}
201210
/>
202211
<Button
203212
className="login-big-button"
@@ -223,12 +232,65 @@ export interface RequestAgreementParams {
223232
serviceURL?: string;
224233
t: FlatI18nTFunction;
225234
}
226-
227-
export function requestAgreement({
235+
export interface PrivacyAgreementData {
236+
title: string;
237+
content: string;
238+
}
239+
export async function getPrivacy(props: {
240+
privacyURL: string;
241+
serviceURL: string;
242+
}): Promise<PrivacyAgreementData | undefined> {
243+
const { privacyURL, serviceURL } = props;
244+
if (FLAT_AGREEMENT_URL) {
245+
const data = await fetch(FLAT_AGREEMENT_URL).then(response => {
246+
return response.json();
247+
});
248+
if (data.content) {
249+
data.content = data.content
250+
.replace(/{{serviceURL}}/g, serviceURL)
251+
.replace(/{{privacyURL}}/g, privacyURL);
252+
}
253+
return data;
254+
}
255+
return undefined;
256+
}
257+
export async function requestAgreement({
228258
t,
229259
privacyURL,
230260
serviceURL,
231261
}: RequestAgreementParams): Promise<boolean> {
262+
if (privacyURL && serviceURL) {
263+
const data = await getPrivacy({ privacyURL, serviceURL });
264+
if (data) {
265+
return await new Promise<boolean>(resolve => {
266+
Modal.confirm({
267+
title: (
268+
<div
269+
style={{
270+
borderBottom: "1px solid #EEEEEE",
271+
textAlign: "center",
272+
lineHeight: "30px",
273+
}}
274+
>
275+
{data.title}
276+
</div>
277+
),
278+
icon: null,
279+
content: (
280+
<div
281+
dangerouslySetInnerHTML={{
282+
__html: data.content,
283+
}}
284+
></div>
285+
),
286+
okText: t("cross-region-auth.agree"),
287+
cancelText: t("cross-region-auth.disagree"),
288+
onOk: () => resolve(true),
289+
onCancel: () => resolve(false),
290+
});
291+
});
292+
}
293+
}
232294
return new Promise<boolean>(resolve =>
233295
Modal.confirm({
234296
content: (
@@ -243,6 +305,7 @@ export function requestAgreement({
243305
</a>
244306
</div>
245307
),
308+
icon: null,
246309
onOk: () => resolve(true),
247310
onCancel: () => resolve(false),
248311
}),

packages/flat-components/src/components/LoginPage/LoginWithPassword/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,15 @@ export const LoginWithPassword: React.FC<LoginWithPasswordProps> = ({
268268
checked={agreed}
269269
privacyURL={privacyURL}
270270
serviceURL={serviceURL}
271-
onChange={setAgreed}
271+
onChange={checked => {
272+
if (checked) {
273+
requestAgreement({ t, privacyURL, serviceURL }).then(agreed => {
274+
setAgreed(agreed);
275+
});
276+
} else {
277+
setAgreed(false);
278+
}
279+
}}
272280
/>
273281

274282
<Button

packages/flat-components/src/components/RegisterModal/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,15 @@ export const RegisterModal: React.FC<RegisterProps> = ({
194194
checked={agreed}
195195
privacyURL={privacyURL}
196196
serviceURL={serviceURL}
197-
onChange={setAgreed}
197+
onChange={checked => {
198+
if (checked) {
199+
requestAgreement({ t, privacyURL, serviceURL }).then(agreed => {
200+
setAgreed(agreed);
201+
});
202+
} else {
203+
setAgreed(false);
204+
}
205+
}}
198206
/>
199207

200208
<Button

packages/flat-i18n/locales/en.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,5 +774,8 @@
774774
"privacyPolicy": "Privacy Policy",
775775
"agree": "agree",
776776
"disagree": "disagree"
777-
}
777+
},
778+
"collect-media-options": "Audio and video data acquisition",
779+
"collect-media-turn-on": "Turn on",
780+
"collect-media-turn-off": "Turn off"
778781
}

packages/flat-i18n/locales/zh-CN.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,10 @@
772772
"desc":"请注意,您正在加入 Agora Flat 海外版用户创建的房间。我们将严格遵守适用的法律法规要求进行数据出境安全评估,采用合理的物理隔离和安全防护措施,确保您的数据仅在您的授权许可下使用。具体内容参见{{serviceAgreement}}与{{privacyPolicy}}",
773773
"serviceAgreement": "服务协议",
774774
"privacyPolicy": "隐私政策",
775-
"agree": "确定",
775+
"agree": "同意",
776776
"disagree": "取消"
777-
}
777+
},
778+
"collect-media-options": "音视频数据采集",
779+
"collect-media-turn-on": "开启",
780+
"collect-media-turn-off": "关闭"
778781
}

packages/flat-pages/src/UserSettingPage/GeneralSettingPage/index.tsx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ import {
2323
LoginPlatform,
2424
deleteAccount,
2525
deleteAccountValidate,
26+
getCollectionAgreement,
2627
loginCheck,
2728
removeBinding,
2829
rename,
30+
setCollectionAgreement,
2931
} from "@netless/flat-server-api";
3032

3133
import { PreferencesStoreContext, GlobalStoreContext } from "../../components/StoreProvider";
@@ -43,12 +45,45 @@ import { BindGitHub } from "./binding/GitHub";
4345
import { BindGoogle } from "./binding/Google";
4446
import { BindingField } from "./BindingField";
4547
import { useBindingList } from "./binding";
48+
import { Region } from "../../utils/join-room-handler";
4649

4750
enum SelectLanguage {
4851
Chinese,
4952
English,
5053
}
5154

55+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
56+
const CollectionAgreement = () => {
57+
const [isAgree, setAgree] = useState(true);
58+
const t = useTranslate();
59+
const sp = useSafePromise();
60+
useEffect(() => {
61+
sp(getCollectionAgreement()).then(res => {
62+
setAgree(res.isAgree);
63+
});
64+
}, [sp]);
65+
async function changeCollectMediaState(event: CheckboxChangeEvent): Promise<void> {
66+
const isAgree = Boolean(event.target.value);
67+
await sp(setCollectionAgreement(isAgree));
68+
setAgree(isAgree);
69+
}
70+
return (
71+
<div className="general-setting-item">
72+
<div className="general-setting-item-title">{t("collect-media-options")}</div>
73+
<div className="join-room-settings">
74+
<Radio.Group value={isAgree} onChange={changeCollectMediaState}>
75+
<Radio value={true}>
76+
<span className="radio-item-inner">{t("collect-media-turn-on")}</span>
77+
</Radio>
78+
<Radio value={false}>
79+
<span className="radio-item-inner">{t("collect-media-turn-off")}</span>
80+
</Radio>
81+
</Radio.Group>
82+
</div>
83+
</div>
84+
);
85+
};
86+
5287
export const GeneralSettingPage = observer(function GeneralSettingPage() {
5388
const globalStore = useContext(GlobalStoreContext);
5489
const preferencesStore = useContext(PreferencesStoreContext);
@@ -73,7 +108,10 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
73108
() => `${FLAT_WEB_BASE_URL}/join/${globalStore.pmi}`,
74109
[globalStore.pmi],
75110
);
76-
111+
const serverRegion = useMemo(
112+
() => globalStore.serverRegionConfig?.server.region,
113+
[globalStore.serverRegionConfig?.server.region],
114+
);
77115
const loginButtons = useMemo(
78116
() => process.env.LOGIN_METHODS.split(",") as LoginButtonProviderType[],
79117
[],
@@ -107,7 +145,6 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
107145
throw error;
108146
}
109147
}
110-
111148
function changeLanguage(event: CheckboxChangeEvent): void {
112149
const language: SelectLanguage = event.target.value;
113150
void FlatI18n.changeLanguage(language === SelectLanguage.Chinese ? "zh-CN" : "en");
@@ -403,6 +440,13 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
403440
</div>
404441
</div>
405442
<hr />
443+
{serverRegion === Region.CN_HZ && (
444+
<>
445+
<CollectionAgreement />
446+
<hr />
447+
</>
448+
)}
449+
406450
<div className="general-setting-item">
407451
<span className="general-setting-item-title">{t("delete-account")}</span>
408452

packages/flat-server-api/src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const FLAT_REGION = process.env.FLAT_REGION;
44
export const SERVER_DOMAINS = process.env.FLAT_SERVER_DOMAINS as unknown as Record<string, string>;
55

66
export const CURRENT_SERVER_DOMAIN = process.env.FLAT_SERVER_DOMAIN;
7+
export const FLAT_AGREEMENT_URL = process.env.FLAT_AGREEMENT_URL;
78

89
export const COOKIE_DOMAIN = CURRENT_SERVER_DOMAIN
910
? CURRENT_SERVER_DOMAIN.slice(CURRENT_SERVER_DOMAIN.indexOf(".") + 1)

packages/flat-server-api/src/login.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,27 @@ export interface RemoveBindingResult {
436436
token: string;
437437
}
438438

439+
export interface SetCollectionAgreementReq {
440+
is_agree_collect_data: boolean;
441+
}
442+
export interface SetCollectionAgreementResult {
443+
userUUID: string;
444+
}
445+
export interface GetCollectionAgreementResult {
446+
isAgree: boolean;
447+
}
448+
export async function getCollectionAgreement(): Promise<GetCollectionAgreementResult> {
449+
return await post<{}, GetCollectionAgreementResult>("user/agreement/get", {});
450+
}
451+
export async function setCollectionAgreement(
452+
isAgree: boolean,
453+
): Promise<SetCollectionAgreementResult> {
454+
return await post<SetCollectionAgreementReq, SetCollectionAgreementResult>(
455+
"user/agreement/set",
456+
{ is_agree_collect_data: isAgree },
457+
);
458+
}
459+
439460
export async function removeBinding(target: LoginPlatform): Promise<RemoveBindingResult> {
440461
return await post<RemoveBindingPayload, RemoveBindingResult>("user/binding/remove", {
441462
target,

0 commit comments

Comments
 (0)