From 94f34a0fdef3934bb838873771af9cd1611e4db3 Mon Sep 17 00:00:00 2001
From: "maruyama.t"
Date: Tue, 5 Dec 2023 09:10:49 +0000
Subject: [PATCH] =?UTF-8?q?Merged=20PR=20606:=20=E7=94=BB=E9=9D=A2?=
=?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=88Terms=E7=94=BB=E9=9D=A2=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3210: 画面修正(Terms画面)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3210)
[Task3211:API修正(バージョン取得API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%2023-1?workitem=3211)
[Task3212:API修正(バージョン更新API))](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%2023-1?workitem=3212)
- このPull Requestでの対象/対象外
Click here to read the terms of use.の文言は多言語対応の対象のため、現在一律同じ文言がでます。
第一~第四階層は
上からEULA,PrivacyNotice,DPAが表示されています
第五階層は、
上から、PrivacyNotice,DPAが表示されています
- 影響範囲(他の機能にも影響があるか)
ユーザアーカイブテーブルにPrivacyNoticeのバージョンを追加
## レビューポイント
同意済みプライバシーポリシーはユーザーアーカイブの対象だと認識しているが正しいか。
termsテーブルのdocument_typeの値をPrivacyNoticeにしているが、PRIVACY_NOTICEにしたほうがよいか。
ユニットテストに不足はないか。
## UIの変更
- Before/Afterのスクショなど
- スクショ置き場
https://ndstokyo.sharepoint.com/sites/Piranha/Shared%20Documents/Forms/AllItems.aspx?csf=1&web=1&e=hzPw9b&cid=7737ed1b%2D0eb4%2D4331%2Da238%2D14dd35b27e18&FolderCTID=0x012000C0DCEE65AC2177479C3C761CD137C9C9&id=%2Fsites%2FPiranha%2FShared%20Documents%2FGeneral%2FOMDS%2F%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%2FTask3210&viewid=786a81cf%2Dd15f%2D4dc2%2D9e55%2Dc7a729fbc72f
## 動作確認状況
- ローカルで確認
## 補足
- 相談、参考資料などがあれば
---
dictation_client/src/api/api.ts | 12 +++++
.../src/features/terms/constants.ts | 1 +
.../src/features/terms/operations.ts | 3 ++
.../src/features/terms/selectors.ts | 6 ++-
.../src/pages/SignupPage/signupConfirm.tsx | 1 +
.../src/pages/TermsPage/index.tsx | 47 +++++++++++++++++--
dictation_client/src/translation/de.json | 1 +
dictation_client/src/translation/en.json | 1 +
dictation_client/src/translation/es.json | 1 +
dictation_client/src/translation/fr.json | 1 +
dictation_server/src/api/odms/openapi.json | 15 +++++-
dictation_server/src/common/test/utility.ts | 2 +
dictation_server/src/constants/index.ts | 1 +
.../features/accounts/accounts.controller.ts | 2 +
.../accounts/accounts.service.spec.ts | 21 +++++++++
.../src/features/accounts/accounts.service.ts | 3 ++
.../src/features/accounts/types/types.ts | 2 +
.../src/features/auth/auth.service.spec.ts | 29 ++++++++++++
.../src/features/auth/auth.service.ts | 22 ++++++---
.../src/features/auth/types/types.ts | 2 +
.../features/files/test/files.service.mock.ts | 1 +
.../features/tasks/test/tasks.service.mock.ts | 1 +
.../src/features/terms/terms.service.spec.ts | 23 ++++++++-
.../src/features/terms/terms.service.ts | 6 ++-
.../src/features/terms/types/types.ts | 1 +
.../src/features/users/types/types.ts | 2 +
.../src/features/users/users.controller.ts | 8 +++-
.../src/features/users/users.service.spec.ts | 13 ++++-
.../src/features/users/users.service.ts | 6 +++
.../accounts/accounts.repository.service.ts | 3 ++
.../terms/terms.repository.service.ts | 15 +++++-
.../repositories/users/entity/user.entity.ts | 6 +++
.../users/users.repository.service.ts | 25 ++++++++--
33 files changed, 261 insertions(+), 22 deletions(-)
diff --git a/dictation_client/src/api/api.ts b/dictation_client/src/api/api.ts
index 2b5689d..b77b7b4 100644
--- a/dictation_client/src/api/api.ts
+++ b/dictation_client/src/api/api.ts
@@ -447,6 +447,12 @@ export interface CreateAccountRequest {
* @memberof CreateAccountRequest
*/
'acceptedEulaVersion': string;
+ /**
+ * 同意済みプライバシーポリシーのバージョン
+ * @type {string}
+ * @memberof CreateAccountRequest
+ */
+ 'acceptedPrivacyNoticeVersion': string;
/**
* 同意済み利用規約のバージョン(DPA)
* @type {string}
@@ -2000,6 +2006,12 @@ export interface UpdateAcceptedVersionRequest {
* @memberof UpdateAcceptedVersionRequest
*/
'acceptedEULAVersion': string;
+ /**
+ * 更新バージョン(PrivacyNotice)
+ * @type {string}
+ * @memberof UpdateAcceptedVersionRequest
+ */
+ 'acceptedPrivacyNoticeVersion': string;
/**
* 更新バージョン(DPA)
* @type {string}
diff --git a/dictation_client/src/features/terms/constants.ts b/dictation_client/src/features/terms/constants.ts
index dd78e43..e9cbd2f 100644
--- a/dictation_client/src/features/terms/constants.ts
+++ b/dictation_client/src/features/terms/constants.ts
@@ -5,4 +5,5 @@
export const TERMS_DOCUMENT_TYPE = {
DPA: "DPA",
EULA: "EULA",
+ PRIVACY_NOTICE: "PrivacyNotice",
} as const;
diff --git a/dictation_client/src/features/terms/operations.ts b/dictation_client/src/features/terms/operations.ts
index 876bb19..f9a1a0d 100644
--- a/dictation_client/src/features/terms/operations.ts
+++ b/dictation_client/src/features/terms/operations.ts
@@ -110,6 +110,7 @@ export const updateAcceptedVersionAsync = createAsyncThunk<
updateAccceptVersions: {
acceptedVerDPA: string;
acceptedVerEULA: string;
+ acceptedVerPrivacyNotice: string;
};
},
{
@@ -140,6 +141,8 @@ export const updateAcceptedVersionAsync = createAsyncThunk<
{
idToken,
acceptedEULAVersion: updateAccceptVersions.acceptedVerEULA,
+ acceptedPrivacyNoticeVersion:
+ updateAccceptVersions.acceptedVerPrivacyNotice,
acceptedDPAVersion: !(TIERS.TIER5 === tier.toString())
? updateAccceptVersions.acceptedVerDPA
: undefined,
diff --git a/dictation_client/src/features/terms/selectors.ts b/dictation_client/src/features/terms/selectors.ts
index 5cd00f7..75f45b9 100644
--- a/dictation_client/src/features/terms/selectors.ts
+++ b/dictation_client/src/features/terms/selectors.ts
@@ -14,7 +14,11 @@ export const selectTermVersions = (state: RootState) => {
(termInfo) => termInfo.documentType === TERMS_DOCUMENT_TYPE.EULA
)?.version || "";
- return { acceptedVerDPA, acceptedVerEULA };
+ const acceptedVerPrivacyNotice =
+ termsInfo.find(
+ (termInfo) => termInfo.documentType === TERMS_DOCUMENT_TYPE.PRIVACY_NOTICE
+ )?.version || "";
+ return { acceptedVerDPA, acceptedVerEULA, acceptedVerPrivacyNotice };
};
export const selectTier = (state: RootState) => state.terms.domain.tier;
diff --git a/dictation_client/src/pages/SignupPage/signupConfirm.tsx b/dictation_client/src/pages/SignupPage/signupConfirm.tsx
index 698e1b6..b4e6a26 100644
--- a/dictation_client/src/pages/SignupPage/signupConfirm.tsx
+++ b/dictation_client/src/pages/SignupPage/signupConfirm.tsx
@@ -40,6 +40,7 @@ const SignupConfirm: React.FC = (): JSX.Element => {
adminMail,
adminPassword,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion: "",
acceptedDpaVersion: "",
token: "",
})
diff --git a/dictation_client/src/pages/TermsPage/index.tsx b/dictation_client/src/pages/TermsPage/index.tsx
index cb45b5d..777a115 100644
--- a/dictation_client/src/pages/TermsPage/index.tsx
+++ b/dictation_client/src/pages/TermsPage/index.tsx
@@ -29,9 +29,12 @@ const TermsPage: React.FC = (): JSX.Element => {
const tier = useSelector(selectTier);
const [isCheckedEula, setIsCheckedEula] = useState(false);
+ const [isCheckedPrivacyNotice, setIsCheckedPrivacyNotice] = useState(false);
const [isCheckedDpa, setIsCheckedDpa] = useState(false);
const [isClickedEulaLink, setIsClickedEulaLink] = useState(false);
+ const [isClickedPrivacyNoticeLink, setIsClickedPrivacyNoticeLink] =
+ useState(false);
const [isClickedDpaLink, setIsClickedDpaLink] = useState(false);
// 画面起動時
@@ -52,9 +55,9 @@ const TermsPage: React.FC = (): JSX.Element => {
// ボタン押下可否判定ロジック
const canClickButton = () => {
if (isTier5()) {
- return isCheckedEula;
+ return isCheckedEula && isCheckedPrivacyNotice;
}
- return isCheckedEula && isCheckedDpa;
+ return isCheckedEula && isCheckedPrivacyNotice && isCheckedDpa;
};
// ボタン押下時処理
@@ -62,7 +65,8 @@ const TermsPage: React.FC = (): JSX.Element => {
if (
localStorageKeyforIdToken &&
updateAccceptVersions.acceptedVerDPA !== "" &&
- updateAccceptVersions.acceptedVerEULA !== ""
+ updateAccceptVersions.acceptedVerEULA !== "" &&
+ updateAccceptVersions.acceptedVerPrivacyNotice !== ""
) {
const { meta } = await dispatch(
updateAcceptedVersionAsync({
@@ -132,7 +136,42 @@ const TermsPage: React.FC = (): JSX.Element => {
- {/* 第五階層以外の場合はEulaのリンクをあわせて表示する */}
+
diff --git a/dictation_client/src/translation/de.json b/dictation_client/src/translation/de.json
index f7e485d..71b532f 100644
--- a/dictation_client/src/translation/de.json
+++ b/dictation_client/src/translation/de.json
@@ -532,6 +532,7 @@
"title": "(de)Terms of Use has updated. Please confirm again.",
"linkOfEula": "(de)Click here to read the terms of use.",
"linkOfDpa": "(de)Click here to read the terms of use.",
+ "linkOfPrivacyNotice": "(de)Click here to read the terms of use.",
"checkBoxForConsent": "(de)Yes, I agree to the terms of use.",
"forOdds": "(de)for ODDS.",
"button": "(de)Continue",
diff --git a/dictation_client/src/translation/en.json b/dictation_client/src/translation/en.json
index 6da4f95..cbf9f66 100644
--- a/dictation_client/src/translation/en.json
+++ b/dictation_client/src/translation/en.json
@@ -532,6 +532,7 @@
"title": "Terms of Use has updated. Please confirm again.",
"linkOfEula": "Click here to read the terms of use.",
"linkOfDpa": "Click here to read the terms of use.",
+ "linkOfPrivacyNotice": "Click here to read the terms of use.",
"checkBoxForConsent": "Yes, I agree to the terms of use.",
"forOdds": "for ODDS.",
"button": "Continue",
diff --git a/dictation_client/src/translation/es.json b/dictation_client/src/translation/es.json
index d6711e3..552edb2 100644
--- a/dictation_client/src/translation/es.json
+++ b/dictation_client/src/translation/es.json
@@ -532,6 +532,7 @@
"title": "(es)Terms of Use has updated. Please confirm again.",
"linkOfEula": "(es)Click here to read the terms of use.",
"linkOfDpa": "(es)Click here to read the terms of use.",
+ "linkOfPrivacyNotice": "(es)Click here to read the terms of use.",
"checkBoxForConsent": "(es)Yes, I agree to the terms of use.",
"forOdds": "(es)for ODDS.",
"button": "(es)Continue",
diff --git a/dictation_client/src/translation/fr.json b/dictation_client/src/translation/fr.json
index d6735e1..e3bf194 100644
--- a/dictation_client/src/translation/fr.json
+++ b/dictation_client/src/translation/fr.json
@@ -532,6 +532,7 @@
"title": "(fr)Terms of Use has updated. Please confirm again.",
"linkOfEula": "(fr)Click here to read the terms of use.",
"linkOfDpa": "(fr)Click here to read the terms of use.",
+ "linkOfPrivacyNotice": "(fr)Click here to read the terms of use.",
"checkBoxForConsent": "(fr)Yes, I agree to the terms of use.",
"forOdds": "(fr)for ODDS.",
"button": "(fr)Continue",
diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json
index 7667921..069d43c 100644
--- a/dictation_server/src/api/odms/openapi.json
+++ b/dictation_server/src/api/odms/openapi.json
@@ -3537,6 +3537,10 @@
"type": "string",
"description": "同意済み利用規約のバージョン(EULA)"
},
+ "acceptedPrivacyNoticeVersion": {
+ "type": "string",
+ "description": "同意済みプライバシーポリシーのバージョン"
+ },
"acceptedDpaVersion": {
"type": "string",
"description": "同意済み利用規約のバージョン(DPA)"
@@ -3550,6 +3554,7 @@
"adminMail",
"adminPassword",
"acceptedEulaVersion",
+ "acceptedPrivacyNoticeVersion",
"acceptedDpaVersion",
"token"
]
@@ -4292,12 +4297,20 @@
"type": "string",
"description": "更新バージョン(EULA)"
},
+ "acceptedPrivacyNoticeVersion": {
+ "type": "string",
+ "description": "更新バージョン(PrivacyNotice)"
+ },
"acceptedDPAVersion": {
"type": "string",
"description": "更新バージョン(DPA)"
}
},
- "required": ["idToken", "acceptedEULAVersion"]
+ "required": [
+ "idToken",
+ "acceptedEULAVersion",
+ "acceptedPrivacyNoticeVersion"
+ ]
},
"UpdateAcceptedVersionResponse": { "type": "object", "properties": {} },
"GetMyUserResponse": {
diff --git a/dictation_server/src/common/test/utility.ts b/dictation_server/src/common/test/utility.ts
index 00b19d7..18dda44 100644
--- a/dictation_server/src/common/test/utility.ts
+++ b/dictation_server/src/common/test/utility.ts
@@ -182,6 +182,8 @@ export const makeTestAccount = async (
role: d?.role ?? 'admin none',
author_id: d?.author_id ?? undefined,
accepted_eula_version: d?.accepted_eula_version ?? '1.0',
+ accepted_privacy_notice_version:
+ d?.accepted_privacy_notice_version ?? '1.0',
accepted_dpa_version: d?.accepted_dpa_version ?? '1.0',
email_verified: d?.email_verified ?? true,
auto_renew: d?.auto_renew ?? true,
diff --git a/dictation_server/src/constants/index.ts b/dictation_server/src/constants/index.ts
index 0f8a7eb..439c7ed 100644
--- a/dictation_server/src/constants/index.ts
+++ b/dictation_server/src/constants/index.ts
@@ -287,6 +287,7 @@ export const MANUAL_RECOVERY_REQUIRED = '[MANUAL_RECOVERY_REQUIRED]';
export const TERM_TYPE = {
EULA: 'EULA',
DPA: 'DPA',
+ PRIVACY_NOTICE: 'PrivacyNotice',
} as const;
/**
diff --git a/dictation_server/src/features/accounts/accounts.controller.ts b/dictation_server/src/features/accounts/accounts.controller.ts
index 04c8e26..619aa2b 100644
--- a/dictation_server/src/features/accounts/accounts.controller.ts
+++ b/dictation_server/src/features/accounts/accounts.controller.ts
@@ -118,6 +118,7 @@ export class AccountsController {
adminPassword,
adminName,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
} = body;
const role = USER_ROLES.NONE;
@@ -134,6 +135,7 @@ export class AccountsController {
adminName,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
diff --git a/dictation_server/src/features/accounts/accounts.service.spec.ts b/dictation_server/src/features/accounts/accounts.service.spec.ts
index 2656aed..27c3715 100644
--- a/dictation_server/src/features/accounts/accounts.service.spec.ts
+++ b/dictation_server/src/features/accounts/accounts.service.spec.ts
@@ -112,6 +112,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -144,6 +145,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
// 作成したアカウントのIDが返ってくるか確認
@@ -161,6 +163,9 @@ describe('createAccount', () => {
expect(account?.primary_admin_user_id).toBe(user?.id);
expect(account?.secondary_admin_user_id).toBe(null);
expect(user?.accepted_eula_version).toBe(acceptedEulaVersion);
+ expect(user?.accepted_privacy_notice_version).toBe(
+ acceptedPrivacyNoticeVersion,
+ );
expect(user?.accepted_dpa_version).toBe(acceptedDpaVersion);
expect(user?.account_id).toBe(accountId);
expect(user?.role).toBe(role);
@@ -195,6 +200,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'admin none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -216,6 +222,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -264,6 +271,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'admin none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -286,6 +294,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -318,6 +327,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -345,6 +355,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -384,6 +395,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -411,6 +423,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -452,6 +465,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -480,6 +494,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -520,6 +535,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -551,6 +567,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -593,6 +610,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -641,6 +659,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
@@ -689,6 +708,7 @@ describe('createAccount', () => {
const username = 'dummy_username';
const role = 'none';
const acceptedEulaVersion = '1.0.0';
+ const acceptedPrivacyNoticeVersion = '1.0.0';
const acceptedDpaVersion = '1.0.0';
overrideAdB2cService(service, {
@@ -734,6 +754,7 @@ describe('createAccount', () => {
username,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
} catch (e) {
diff --git a/dictation_server/src/features/accounts/accounts.service.ts b/dictation_server/src/features/accounts/accounts.service.ts
index 49f61f2..668f815 100644
--- a/dictation_server/src/features/accounts/accounts.service.ts
+++ b/dictation_server/src/features/accounts/accounts.service.ts
@@ -176,6 +176,7 @@ export class AccountsService {
username: string,
role: string,
acceptedEulaVersion: string,
+ acceptedPrivacyNoticeVersion: string,
acceptedDpaVersion: string,
): Promise<{ accountId: number; userId: number; externalUserId: string }> {
this.logger.log(
@@ -185,6 +186,7 @@ export class AccountsService {
`dealerAccountId: ${dealerAccountId}, ` +
`role: ${role}, ` +
`acceptedEulaVersion: ${acceptedEulaVersion}, ` +
+ `acceptedPrivacyNoticeVersion: ${acceptedPrivacyNoticeVersion}, ` +
`acceptedDpaVersion: ${acceptedDpaVersion} };`,
);
try {
@@ -233,6 +235,7 @@ export class AccountsService {
externalUser.sub,
role,
acceptedEulaVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDpaVersion,
);
account = newAccount;
diff --git a/dictation_server/src/features/accounts/types/types.ts b/dictation_server/src/features/accounts/types/types.ts
index 8a555d6..276fd0e 100644
--- a/dictation_server/src/features/accounts/types/types.ts
+++ b/dictation_server/src/features/accounts/types/types.ts
@@ -45,6 +45,8 @@ export class CreateAccountRequest {
adminPassword: string;
@ApiProperty({ description: '同意済み利用規約のバージョン(EULA)' })
acceptedEulaVersion: string;
+ @ApiProperty({ description: '同意済みプライバシーポリシーのバージョン' })
+ acceptedPrivacyNoticeVersion: string;
@ApiProperty({ description: '同意済み利用規約のバージョン(DPA)' })
acceptedDpaVersion: string;
@ApiProperty({ description: 'reCAPTCHA Token' })
diff --git a/dictation_server/src/features/auth/auth.service.spec.ts b/dictation_server/src/features/auth/auth.service.spec.ts
index 4451cb0..f978889 100644
--- a/dictation_server/src/features/auth/auth.service.spec.ts
+++ b/dictation_server/src/features/auth/auth.service.spec.ts
@@ -196,6 +196,7 @@ describe('checkIsAcceptedLatestVersion', () => {
};
await createTermInfo(source, 'EULA', '1.0');
+ await createTermInfo(source, 'PrivacyNotice', '1.0');
await createTermInfo(source, 'DPA', '1.0');
const result = await service.isAcceptedLatestVersion(context, idToken);
expect(result).toBe(true);
@@ -219,6 +220,7 @@ describe('checkIsAcceptedLatestVersion', () => {
};
await createTermInfo(source, 'EULA', '1.0');
+ await createTermInfo(source, 'PrivacyNotice', '1.0');
await createTermInfo(source, 'DPA', '1.0');
const result = await service.isAcceptedLatestVersion(context, idToken);
expect(result).toBe(true);
@@ -242,6 +244,7 @@ describe('checkIsAcceptedLatestVersion', () => {
};
await createTermInfo(source, 'EULA', '1.1');
+ await createTermInfo(source, 'PrivacyNotice', '1.0');
await createTermInfo(source, 'DPA', '1.0');
const result = await service.isAcceptedLatestVersion(context, idToken);
expect(result).toBe(false);
@@ -265,6 +268,7 @@ describe('checkIsAcceptedLatestVersion', () => {
};
await createTermInfo(source, 'EULA', '1.1');
+ await createTermInfo(source, 'PrivacyNotice', '1.0');
await createTermInfo(source, 'DPA', '1.0');
const result = await service.isAcceptedLatestVersion(context, idToken);
expect(result).toBe(false);
@@ -288,10 +292,35 @@ describe('checkIsAcceptedLatestVersion', () => {
};
await createTermInfo(source, 'EULA', '1.0');
+ await createTermInfo(source, 'PrivacyNotice', '1.0');
await createTermInfo(source, 'DPA', '1.1');
const result = await service.isAcceptedLatestVersion(context, idToken);
expect(result).toBe(false);
});
+
+ it('同意済みプライバシーポリシーが最新でないときにチェックが通らないこと(第一~第四)', async () => {
+ if (!source) fail();
+ const module = await makeTestingModule(source);
+ if (!module) fail();
+ const service = module.get(AuthService);
+ const { admin } = await makeTestAccount(source, {
+ tier: 4,
+ });
+ const context = makeContext(uuidv4());
+
+ const idToken = {
+ emails: [],
+ sub: admin.external_id,
+ exp: 0,
+ iat: 0,
+ };
+
+ await createTermInfo(source, 'EULA', '1.0');
+ await createTermInfo(source, 'PrivacyNotice', '1.1');
+ await createTermInfo(source, 'DPA', '1.0');
+ const result = await service.isAcceptedLatestVersion(context, idToken);
+ expect(result).toBe(false);
+ });
});
describe('generateDelegationRefreshToken', () => {
diff --git a/dictation_server/src/features/auth/auth.service.ts b/dictation_server/src/features/auth/auth.service.ts
index 543ca12..dbcdfc3 100644
--- a/dictation_server/src/features/auth/auth.service.ts
+++ b/dictation_server/src/features/auth/auth.service.ts
@@ -689,28 +689,38 @@ export class AuthService {
const {
acceptedEulaVersion,
latestEulaVersion,
+ acceptedPrivacyNoticeVersion,
+ latestPrivacyNoticeVersion,
acceptedDpaVersion,
latestDpaVersion,
tier,
} = await this.usersRepository.getAcceptedAndLatestVersion(idToken.sub);
- // 第五階層はEULAのみ判定
+ // 第五階層はEULAとPrivacyNoticeのみ判定
if (tier === TIERS.TIER5) {
- if (!acceptedEulaVersion) {
+ if (!acceptedEulaVersion || !acceptedPrivacyNoticeVersion) {
return false;
}
// 最新バージョンに同意済みか判定
const eulaAccepted = acceptedEulaVersion === latestEulaVersion;
- return eulaAccepted;
+ const privacyNoticeAccepted =
+ acceptedPrivacyNoticeVersion === latestPrivacyNoticeVersion;
+ return eulaAccepted && privacyNoticeAccepted;
} else {
- // 第一~第四階層はEULA、DPAを判定
- if (!acceptedEulaVersion || !acceptedDpaVersion) {
+ // 第一~第四階層はEULA、PrivacyNotice、DPAを判定
+ if (
+ !acceptedEulaVersion ||
+ !acceptedPrivacyNoticeVersion ||
+ !acceptedDpaVersion
+ ) {
return false;
}
// 最新バージョンに同意済みか判定
const eulaAccepted = acceptedEulaVersion === latestEulaVersion;
+ const privacyNoticeAccepted =
+ acceptedPrivacyNoticeVersion === latestPrivacyNoticeVersion;
const dpaAccepted = acceptedDpaVersion === latestDpaVersion;
- return eulaAccepted && dpaAccepted;
+ return eulaAccepted && privacyNoticeAccepted && dpaAccepted;
}
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
diff --git a/dictation_server/src/features/auth/types/types.ts b/dictation_server/src/features/auth/types/types.ts
index 1be9570..c031508 100644
--- a/dictation_server/src/features/auth/types/types.ts
+++ b/dictation_server/src/features/auth/types/types.ts
@@ -22,8 +22,10 @@ export class AccessTokenRequest {}
export type TermsCheckInfo = {
tier: number;
acceptedEulaVersion?: string;
+ acceptedPrivacyNoticeVersion?: string;
acceptedDpaVersion?: string;
latestEulaVersion: string;
+ latestPrivacyNoticeVersion: string;
latestDpaVersion: string;
};
diff --git a/dictation_server/src/features/files/test/files.service.mock.ts b/dictation_server/src/features/files/test/files.service.mock.ts
index a5b8f06..c69e7bf 100644
--- a/dictation_server/src/features/files/test/files.service.mock.ts
+++ b/dictation_server/src/features/files/test/files.service.mock.ts
@@ -139,6 +139,7 @@ export const makeDefaultUsersRepositoryMockValue =
role: 'none',
author_id: '',
accepted_eula_version: '1.0',
+ accepted_privacy_notice_version: '1.0',
accepted_dpa_version: '1.0',
email_verified: true,
deleted_at: null,
diff --git a/dictation_server/src/features/tasks/test/tasks.service.mock.ts b/dictation_server/src/features/tasks/test/tasks.service.mock.ts
index cf5aa71..5d5d97c 100644
--- a/dictation_server/src/features/tasks/test/tasks.service.mock.ts
+++ b/dictation_server/src/features/tasks/test/tasks.service.mock.ts
@@ -470,6 +470,7 @@ const defaultTasksRepositoryMockValue: {
external_id: 'userId',
role: 'typist',
accepted_eula_version: '',
+ accepted_privacy_notice_version: '',
accepted_dpa_version: '',
email_verified: true,
auto_renew: true,
diff --git a/dictation_server/src/features/terms/terms.service.spec.ts b/dictation_server/src/features/terms/terms.service.spec.ts
index 772e9f5..6ff1176 100644
--- a/dictation_server/src/features/terms/terms.service.spec.ts
+++ b/dictation_server/src/features/terms/terms.service.spec.ts
@@ -34,6 +34,8 @@ describe('利用規約取得', () => {
await createTermInfo(source, 'EULA', 'v1.0');
await createTermInfo(source, 'EULA', 'v1.1');
+ await createTermInfo(source, 'PrivacyNotice', 'v1.0');
+ await createTermInfo(source, 'PrivacyNotice', 'v1.1');
await createTermInfo(source, 'DPA', 'v1.0');
await createTermInfo(source, 'DPA', 'v1.2');
@@ -42,8 +44,10 @@ describe('利用規約取得', () => {
expect(result[0].documentType).toBe('EULA');
expect(result[0].version).toBe('v1.1');
- expect(result[1].documentType).toBe('DPA');
- expect(result[1].version).toBe('v1.2');
+ expect(result[1].documentType).toBe('PrivacyNotice');
+ expect(result[1].version).toBe('v1.1');
+ expect(result[2].documentType).toBe('DPA');
+ expect(result[2].version).toBe('v1.2');
});
it('利用規約情報(EULA、DPA両方)が存在しない場合エラーとなる', async () => {
@@ -75,6 +79,21 @@ describe('利用規約取得', () => {
);
});
+ it('利用規約情報(PrivacyNoticeのみ)が存在しない場合エラーとなる', async () => {
+ if (!source) fail();
+ const module = await makeTestingModule(source);
+ if (!module) fail();
+ const service = module.get(TermsService);
+ await createTermInfo(source, 'PrivacyNotice', 'v1.0');
+ const context = makeContext(uuidv4());
+ await expect(service.getTermsInfo(context)).rejects.toEqual(
+ new HttpException(
+ makeErrorResponse('E009999'),
+ HttpStatus.INTERNAL_SERVER_ERROR,
+ ),
+ );
+ });
+
it('利用規約情報(DPAのみ)が存在しない場合エラーとなる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
diff --git a/dictation_server/src/features/terms/terms.service.ts b/dictation_server/src/features/terms/terms.service.ts
index 65137a1..ee52415 100644
--- a/dictation_server/src/features/terms/terms.service.ts
+++ b/dictation_server/src/features/terms/terms.service.ts
@@ -19,13 +19,17 @@ export class TermsService {
`[IN] [${context.getTrackingId()}] ${this.getTermsInfo.name}`,
);
try {
- const { eulaVersion, dpaVersion } =
+ const { eulaVersion, privacyNoticeVersion, dpaVersion } =
await this.termsRepository.getLatestTermsInfo();
return [
{
documentType: TERM_TYPE.EULA,
version: eulaVersion,
},
+ {
+ documentType: TERM_TYPE.PRIVACY_NOTICE,
+ version: privacyNoticeVersion,
+ },
{
documentType: TERM_TYPE.DPA,
version: dpaVersion,
diff --git a/dictation_server/src/features/terms/types/types.ts b/dictation_server/src/features/terms/types/types.ts
index 6a45eae..479960e 100644
--- a/dictation_server/src/features/terms/types/types.ts
+++ b/dictation_server/src/features/terms/types/types.ts
@@ -13,5 +13,6 @@ export class GetTermsInfoResponse {
export type TermsVersion = {
eulaVersion: string;
+ privacyNoticeVersion: string;
dpaVersion: string;
};
diff --git a/dictation_server/src/features/users/types/types.ts b/dictation_server/src/features/users/types/types.ts
index 9f48418..d21f72d 100644
--- a/dictation_server/src/features/users/types/types.ts
+++ b/dictation_server/src/features/users/types/types.ts
@@ -263,6 +263,8 @@ export class UpdateAcceptedVersionRequest {
idToken: string;
@ApiProperty({ description: '更新バージョン(EULA)' })
acceptedEULAVersion: string;
+ @ApiProperty({ description: '更新バージョン(PrivacyNotice)' })
+ acceptedPrivacyNoticeVersion: string;
@ApiProperty({ description: '更新バージョン(DPA)', required: false })
acceptedDPAVersion?: string;
}
diff --git a/dictation_server/src/features/users/users.controller.ts b/dictation_server/src/features/users/users.controller.ts
index a92bbd2..9f88897 100644
--- a/dictation_server/src/features/users/users.controller.ts
+++ b/dictation_server/src/features/users/users.controller.ts
@@ -627,7 +627,12 @@ export class UsersController {
async updateAcceptedVersion(
@Body() body: UpdateAcceptedVersionRequest,
): Promise {
- const { idToken, acceptedEULAVersion, acceptedDPAVersion } = body;
+ const {
+ idToken,
+ acceptedEULAVersion,
+ acceptedPrivacyNoticeVersion,
+ acceptedDPAVersion,
+ } = body;
const context = makeContext(uuidv4());
@@ -650,6 +655,7 @@ export class UsersController {
context,
verifiedIdToken.sub,
acceptedEULAVersion,
+ acceptedPrivacyNoticeVersion,
acceptedDPAVersion,
);
return {};
diff --git a/dictation_server/src/features/users/users.service.spec.ts b/dictation_server/src/features/users/users.service.spec.ts
index 83894ee..cea6f31 100644
--- a/dictation_server/src/features/users/users.service.spec.ts
+++ b/dictation_server/src/features/users/users.service.spec.ts
@@ -208,6 +208,7 @@ describe('UsersService.confirmUserAndInitPassword', () => {
account_id: 1,
role: 'None',
accepted_eula_version: 'string',
+ accepted_privacy_notice_version: 'string',
accepted_dpa_version: 'string',
email_verified: false,
created_by: 'string;',
@@ -259,6 +260,7 @@ describe('UsersService.confirmUserAndInitPassword', () => {
account_id: 1,
role: 'None',
accepted_eula_version: 'string',
+ accepted_privacy_notice_version: 'string',
accepted_dpa_version: 'string',
email_verified: false,
created_by: 'string;',
@@ -306,6 +308,7 @@ describe('UsersService.confirmUserAndInitPassword', () => {
account_id: 1,
role: 'None',
accepted_eula_version: 'string',
+ accepted_privacy_notice_version: 'string',
accepted_dpa_version: 'string',
email_verified: true,
created_by: 'string;',
@@ -358,6 +361,7 @@ describe('UsersService.confirmUserAndInitPassword', () => {
account_id: 1,
role: 'None',
accepted_eula_version: 'string',
+ accepted_privacy_notice_version: 'string',
accepted_dpa_version: 'string',
email_verified: false,
created_by: 'string;',
@@ -2617,7 +2621,12 @@ describe('UsersService.updateAcceptedVersion', () => {
const context = makeContext(uuidv4());
const service = module.get(UsersService);
- await service.updateAcceptedVersion(context, admin.external_id, 'v2.0');
+ await service.updateAcceptedVersion(
+ context,
+ admin.external_id,
+ 'v2.0',
+ 'v2.0',
+ );
const user = await getUser(source, admin.id);
expect(user?.accepted_eula_version).toBe('v2.0');
@@ -2637,6 +2646,7 @@ describe('UsersService.updateAcceptedVersion', () => {
context,
admin.external_id,
'v2.0',
+ 'v2.0',
'v3.0',
);
const user = await getUser(source, admin.id);
@@ -2660,6 +2670,7 @@ describe('UsersService.updateAcceptedVersion', () => {
context,
admin.external_id,
'v2.0',
+ 'v2.0',
undefined,
),
).rejects.toEqual(
diff --git a/dictation_server/src/features/users/users.service.ts b/dictation_server/src/features/users/users.service.ts
index cf82fd5..60e3e92 100644
--- a/dictation_server/src/features/users/users.service.ts
+++ b/dictation_server/src/features/users/users.service.ts
@@ -403,6 +403,7 @@ export class UsersService {
role,
accepted_dpa_version: null,
accepted_eula_version: null,
+ accepted_privacy_notice_version: null,
encryption: false,
encryption_password: null,
prompt: false,
@@ -422,6 +423,7 @@ export class UsersService {
prompt: prompt ?? false,
accepted_dpa_version: null,
accepted_eula_version: null,
+ accepted_privacy_notice_version: null,
};
default:
//不正なroleが指定された場合はログを出力してエラーを返す
@@ -1044,12 +1046,14 @@ export class UsersService {
* @param context
* @param idToken
* @param eulaVersion
+ * @param privacyNoticeVersion
* @param dpaVersion
*/
async updateAcceptedVersion(
context: Context,
externalId: string,
eulaVersion: string,
+ privacyNoticeVersion: string,
dpaVersion?: string,
): Promise {
this.logger.log(
@@ -1058,6 +1062,7 @@ export class UsersService {
} | params: { ` +
`externalId: ${externalId}, ` +
`eulaVersion: ${eulaVersion}, ` +
+ `privacyNoticeVersion: ${privacyNoticeVersion}, ` +
`dpaVersion: ${dpaVersion}, };`,
);
@@ -1065,6 +1070,7 @@ export class UsersService {
await this.usersRepository.updateAcceptedTermsVersion(
externalId,
eulaVersion,
+ privacyNoticeVersion,
dpaVersion,
);
} catch (e) {
diff --git a/dictation_server/src/repositories/accounts/accounts.repository.service.ts b/dictation_server/src/repositories/accounts/accounts.repository.service.ts
index 1df7d13..d7762bd 100644
--- a/dictation_server/src/repositories/accounts/accounts.repository.service.ts
+++ b/dictation_server/src/repositories/accounts/accounts.repository.service.ts
@@ -127,6 +127,7 @@ export class AccountsRepositoryService {
adminExternalUserId: string,
adminUserRole: string,
adminUserAcceptedEulaVersion?: string,
+ adminUserAcceptedPrivacyNoticeVersion?: string,
adminUserAcceptedDpaVersion?: string,
): Promise<{ newAccount: Account; adminUser: User }> {
return await this.dataSource.transaction(async (entityManager) => {
@@ -148,6 +149,8 @@ export class AccountsRepositoryService {
user.external_id = adminExternalUserId;
user.role = adminUserRole;
user.accepted_eula_version = adminUserAcceptedEulaVersion ?? null;
+ user.accepted_privacy_notice_version =
+ adminUserAcceptedPrivacyNoticeVersion ?? null;
user.accepted_dpa_version = adminUserAcceptedDpaVersion ?? null;
}
const usersRepo = entityManager.getRepository(User);
diff --git a/dictation_server/src/repositories/terms/terms.repository.service.ts b/dictation_server/src/repositories/terms/terms.repository.service.ts
index 7c79f24..7deee0f 100644
--- a/dictation_server/src/repositories/terms/terms.repository.service.ts
+++ b/dictation_server/src/repositories/terms/terms.repository.service.ts
@@ -24,6 +24,14 @@ export class TermsRepositoryService {
id: 'DESC',
},
});
+ const latestPrivacyNoticeInfo = await termRepo.findOne({
+ where: {
+ document_type: TERM_TYPE.PRIVACY_NOTICE,
+ },
+ order: {
+ id: 'DESC',
+ },
+ });
const latestDpaInfo = await termRepo.findOne({
where: {
document_type: TERM_TYPE.DPA,
@@ -33,13 +41,16 @@ export class TermsRepositoryService {
},
});
- if (!latestEulaInfo || !latestDpaInfo) {
+ if (!latestEulaInfo || !latestPrivacyNoticeInfo || !latestDpaInfo) {
throw new TermInfoNotFoundError(
- `Terms info is not found. latestEulaInfo: ${latestEulaInfo}, latestDpaInfo: ${latestDpaInfo}`,
+ `Terms info is not found. latestEulaInfo: ${latestEulaInfo},
+ latestPrivacyNoticeInfo: ${latestPrivacyNoticeInfo},
+ latestDpaInfo: ${latestDpaInfo}`,
);
}
return {
eulaVersion: latestEulaInfo.version,
+ privacyNoticeVersion: latestEulaInfo.version,
dpaVersion: latestDpaInfo.version,
};
});
diff --git a/dictation_server/src/repositories/users/entity/user.entity.ts b/dictation_server/src/repositories/users/entity/user.entity.ts
index 34d0bca..0f4e57c 100644
--- a/dictation_server/src/repositories/users/entity/user.entity.ts
+++ b/dictation_server/src/repositories/users/entity/user.entity.ts
@@ -34,6 +34,9 @@ export class User {
@Column({ nullable: true, type: 'varchar' })
accepted_eula_version: string | null;
+ @Column({ nullable: true, type: 'varchar' })
+ accepted_privacy_notice_version: string | null;
+
@Column({ nullable: true, type: 'varchar' })
accepted_dpa_version: string | null;
@@ -112,6 +115,9 @@ export class UserArchive {
@Column({ nullable: true, type: 'varchar' })
accepted_eula_version: string | null;
+ @Column({ nullable: true, type: 'varchar' })
+ accepted_privacy_notice_version: string | null;
+
@Column({ nullable: true, type: 'varchar' })
accepted_dpa_version: string | null;
diff --git a/dictation_server/src/repositories/users/users.repository.service.ts b/dictation_server/src/repositories/users/users.repository.service.ts
index af179e9..7cfec4d 100644
--- a/dictation_server/src/repositories/users/users.repository.service.ts
+++ b/dictation_server/src/repositories/users/users.repository.service.ts
@@ -360,7 +360,7 @@ export class UsersRepositoryService {
},
where: { account_id: accountId },
});
-
+
return dbUsers;
});
}
@@ -471,6 +471,14 @@ export class UsersRepositoryService {
id: 'DESC',
},
});
+ const latestPrivacyNoticeInfo = await termRepo.findOne({
+ where: {
+ document_type: TERM_TYPE.PRIVACY_NOTICE,
+ },
+ order: {
+ id: 'DESC',
+ },
+ });
const latestDpaInfo = await termRepo.findOne({
where: {
document_type: TERM_TYPE.DPA,
@@ -479,16 +487,18 @@ export class UsersRepositoryService {
id: 'DESC',
},
});
-
- if (!latestEulaInfo || !latestDpaInfo) {
+ if (!latestEulaInfo || !latestPrivacyNoticeInfo || !latestDpaInfo) {
throw new TermInfoNotFoundError(`Terms info is not found.`);
}
return {
tier: user.account.tier,
acceptedEulaVersion: user.accepted_eula_version ?? undefined,
+ acceptedPrivacyNoticeVersion:
+ user.accepted_privacy_notice_version ?? undefined,
acceptedDpaVersion: user.accepted_dpa_version ?? undefined,
latestEulaVersion: latestEulaInfo.version,
+ latestPrivacyNoticeVersion: latestPrivacyNoticeInfo.version,
latestDpaVersion: latestDpaInfo.version,
};
});
@@ -498,12 +508,14 @@ export class UsersRepositoryService {
* 同意済み利用規約のバージョンを更新する
* @param externalId
* @param eulaVersion
+ * @param privacyNoticeVersion
* @param dpaVersion
* @returns update
*/
async updateAcceptedTermsVersion(
externalId: string,
eulaVersion: string,
+ privacyNoticeVersion: string,
dpaVersion: string | undefined,
): Promise {
await this.dataSource.transaction(async (entityManager) => {
@@ -531,6 +543,11 @@ export class UsersRepositoryService {
if (!eulaVersion) {
throw new UpdateTermsVersionNotSetError(`EULA version param not set.`);
}
+ if (!privacyNoticeVersion) {
+ throw new UpdateTermsVersionNotSetError(
+ `PrivacyNotice version param not set.`,
+ );
+ }
if (user.account.tier !== TIERS.TIER5 && !dpaVersion) {
throw new UpdateTermsVersionNotSetError(
`DPA version param not set. User's tier: ${user.account.tier}`,
@@ -538,6 +555,8 @@ export class UsersRepositoryService {
}
user.accepted_eula_version = eulaVersion;
+ user.accepted_privacy_notice_version =
+ privacyNoticeVersion ?? user.accepted_privacy_notice_version;
user.accepted_dpa_version = dpaVersion ?? user.accepted_dpa_version;
await userRepo.update({ id: user.id }, user);
});