1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
17import ability from '@ohos.ability.ability';
18import dlpPermission from '@ohos.dlpPermission';
19import hiSysEvent from '@ohos.hiSysEvent';
20import router from '@ohos.router';
21import picker from '@ohos.file.picker';
22import fileUri from '@ohos.file.fileuri';
23import fs from '@ohos.file.fs';
24import osAccount from '@ohos.account.osAccount';
25import { BusinessError } from '@ohos.base';
26import common from '@ohos.app.ability.common';
27import { EncryptingPanel } from '../common/encryptionComponents/encrypting';
28import { DlpAlertDialog } from '../common/components/dlp_alert_dialog';
29import {
30  PermissionType,
31  getOsAccountInfo,
32  checkDomainAccountInfo,
33  getUserId,
34  removeDuplicate,
35  directionStatus,
36  AuthAccount,
37  getFileUriByPath,
38  sendDlpFileCreateProperties,
39  sendDlpManagerFileConfiguration,
40  getFileSizeByUri
41} from '../common/utils';
42import Constants from '../common/constant';
43import {
44  permissionTypeSelect,
45  validDateTypeMenu,
46  validDateTypeMenuItem
47} from '../common/encryptionComponents/permission_type_select';
48import { AddStaff } from '../common/encryptionComponents/AddStaff';
49import GlobalContext from '../common/GlobalContext';
50import IDLDLPProperty from '../serviceExtensionAbility/sequenceable/dlpClass';
51import { IAuthUser } from '../serviceExtensionAbility/sequenceable/dlpClass';
52import HomeFeature from '../feature/HomeFeature';
53import { GetAlertMessage } from '../common/GetAlertMessage';
54import { HiLog } from '../common/HiLog';
55import FileUtils, { FileMsg } from '../common/FileUtils';
56import { SystemUtils } from '../common/systemUtils';
57
58const TAG = 'Encrypt';
59let abilityResult: ability.AbilityResult = {
60  'resultCode': 0,
61  'want': {}
62};
63
64interface dlpDataType {
65  ownerAccount: string;
66  ownerAccountID: string;
67  ownerAccountType: number;
68  authUserList: Array<dlpPermission.AuthUser>;
69  contactAccount: string;
70  offlineAccess: boolean;
71  everyoneAccessList: Array<dlpPermission.DLPFileAccess>;
72}
73let defaultDlpProperty: dlpPermission.DLPProperty = {
74  ownerAccount: '',
75  ownerAccountType: dlpPermission.AccountType.DOMAIN_ACCOUNT,
76  authUserList: [],
77  contactAccount: '',
78  offlineAccess: true,
79  ownerAccountID: '',
80  everyoneAccessList: []
81};
82
83@Component
84struct DlpDialog {
85  @State dlpProperty: dlpDataType =
86    GlobalContext.load('dlpProperty') !== undefined ? GlobalContext.load('dlpProperty') : defaultDlpProperty;
87  private homeFeature: HomeFeature = GlobalContext.load('homeFeature');
88  @State session: UIExtensionContentSession | undefined =
89    storage === undefined ? undefined : storage.get<UIExtensionContentSession>('session');
90  srcFileName: string = '';
91  isDlpFile: boolean = false;
92  linkFileName: string = '';
93  dlpAlertDialog?: CustomDialogController;
94  @State directionStatus: number = 0;
95  @State authPerm: number = 2;
96  @State handlePopupReadOnly: boolean = false;
97  @State handlePopupEdit: boolean = false;
98  @State processing: boolean = false;
99  @State prepareData: boolean = false;
100  @State validity: Date = AppStorage.get('validity') || new Date();
101  @State selectedIndex: number = AppStorage.get('permanent') === false ? 1 : 0;
102  @State permissionDict: PermissionType[] = [
103    {
104      value: $r('app.string.PERMISSION_TYPE_SELECT_TARGET'), data: 'target', index: 0
105    } as PermissionType,
106    {
107      value: $r('app.string.PERMISSION_TYPE_SELECT_ALL'), data: 'all', index: 1
108    } as PermissionType,
109    {
110      value: $r('app.string.PERMISSION_TYPE_SELECT_SELF'), data: 'self', index: 2
111    } as PermissionType
112  ];
113  @State isAccountCheckSuccess: boolean = true;
114  @State staffDataArrayReadOnly: AuthAccount[] = [];
115  @State staffDataArrayEdit: AuthAccount[] = [];
116  @State selectedPermissionTypeReadOnly: PermissionType =
117    { data: '', value: { id: 0, type: 0, params: [], bundleName: '', moduleName: '' }, index: -1 };
118  @State selectedPermissionTypeEdit: PermissionType =
119    { data: '', value: { id: 0, type: 0, params: [], bundleName: '', moduleName: '' }, index: -1 };
120
121  @Builder popupBuilderReadOnly() {
122    Row() {
123      Text($r('app.string.header_title_readonly_tips'))
124        .fontFamily('HarmonyHeiTi')
125        .fontSize($r('sys.float.ohos_id_text_size_body2'))
126        .fontColor($r('sys.color.ohos_id_color_text_primary'))
127    }
128    .width(Constants.HEADER_COLUMN_MESSAGE_TIPS)
129    .padding({
130      left: Constants.ROW_FONT_SIZE,
131      right: Constants.ROW_FONT_SIZE,
132      top: Constants.DA_MARGIN_TOP,
133      bottom: Constants.DA_MARGIN_TOP
134    })
135  }
136
137  @Builder popupBuilderEdit() {
138    Row() {
139      Text($r('app.string.header_title_edit_tips'))
140        .fontSize($r('sys.float.ohos_id_text_size_body2'))
141        .fontColor($r('sys.color.ohos_id_color_text_primary'))
142    }
143    .width(Constants.HEADER_COLUMN_MESSAGE_TIPS)
144    .padding({
145      left: Constants.ROW_FONT_SIZE,
146      right: Constants.ROW_FONT_SIZE,
147      top: Constants.DA_MARGIN_TOP,
148      bottom: Constants.DA_MARGIN_TOP
149    })
150  }
151
152  @Builder
153  MenuBuilder() {
154    validDateTypeMenuItem({ selectedIndex: $selectedIndex });
155  }
156
157  showErrorDialog(title: string | Resource, message: string | Resource) {
158    this.dlpAlertDialog = new CustomDialogController({
159      builder: DlpAlertDialog({
160        title: title,
161        message: message,
162        action: () => {
163        }
164      }),
165      autoCancel: false,
166      customStyle: true,
167      maskColor: Constants.TRANSPARENT_BACKGROUND_COLOR
168    })
169    this.dlpAlertDialog.open();
170  }
171
172  showErrorDialogNoTitle(message: Resource) {
173    this.dlpAlertDialog = new CustomDialogController({
174      builder: DlpAlertDialog({
175        message: message,
176        action: () => {
177        }
178      }),
179      autoCancel: false,
180      customStyle: true,
181      maskColor: Constants.TRANSPARENT_BACKGROUND_COLOR
182    })
183    this.dlpAlertDialog.open();
184  }
185
186  async sendDlpFileCreateFault(code: number, reason?: string) {
187    let event: hiSysEvent.SysEventInfo = {
188      domain: 'DLP',
189      name: 'DLP_FILE_CREATE',
190      eventType: hiSysEvent.EventType.FAULT,
191      params: {
192        'CODE': code,
193        'REASON': reason
194      } as Record<string, number | string>
195    };
196
197    try {
198      let userId = await getUserId();
199      if (event.params) {
200        event.params['USER_ID'] = userId;
201        await hiSysEvent.write(event);
202      }
203    } catch (err) {
204      HiLog.error(TAG, `sendDlpFileCreateFault failed, err: ${JSON.stringify(err)}`);
205    }
206  }
207
208  async sendDlpFileCreateEvent(code: number) {
209    let event: hiSysEvent.SysEventInfo = {
210      domain: 'DLP',
211      name: 'DLP_FILE_CREATE_EVENT',
212      eventType: hiSysEvent.EventType.BEHAVIOR,
213      params: {
214        'CODE': code,
215      } as Record<string, number>
216    };
217    try {
218      let userId = await getUserId();
219      if (event.params) {
220        event.params['USER_ID'] = userId;
221        await hiSysEvent.write(event);
222      }
223    } catch (err) {
224      HiLog.error(TAG, `sendDlpFileCreateEvent, err: ${JSON.stringify(err)}`);
225    }
226  }
227
228  async catchProcess() {
229    this.processing = false;
230    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
231      HiLog.info(TAG, `resumeFuseLink: ${this.srcFileName}`);
232      this.homeFeature.resumeFuseLinkHome(GlobalContext.load('uri'), (err: number) => {
233        if (err !== 0) {
234          HiLog.error(TAG, `resumeFuseLink failed: ${err}`);
235        }
236      });
237    }
238  }
239
240  async setUserStat() {
241    if (this.selectedPermissionTypeReadOnly.index === 0) {
242      AppStorage.setOrCreate('hiReadScope', 'User');
243    } else if (this.selectedPermissionTypeReadOnly.index === 1) {
244      AppStorage.setOrCreate('hiReadScope', 'Everyone');
245    }
246    if (this.selectedPermissionTypeEdit.index === 0) {
247      AppStorage.setOrCreate('hiWriteScope', 'User');
248    } else if (this.selectedPermissionTypeEdit.index === 1) {
249      AppStorage.setOrCreate('hiWriteScope', 'Everyone');
250    } else {
251      AppStorage.setOrCreate('hiWriteScope', 'Onlyme');
252    }
253  }
254
255  async changeEncrypt() {
256    this.processing = true;
257    await this.setUserStat();
258    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
259      try {
260        await this.stopFuseLinkHome();
261      } catch {
262        return;
263      }
264    }
265    let filePath = getContext(this).filesDir + '/' + (new Date().getTime());
266    let file: fs.File | undefined;
267    try {
268      file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
269      HiLog.info(TAG, `open temp file`);
270    } catch (err) {
271      HiLog.error(TAG, `open temp failed: ${JSON.stringify(err)}`);
272      this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR'));
273      await this.catchProcess();
274      return;
275    } finally {
276      if (file) {
277        fs.closeSync(file);
278      }
279    };
280    let filePathUri = getFileUriByPath(filePath);
281    try {
282      await new Promise<void>((resolve, reject) => {
283        this.homeFeature.recoverDLPFileHome(GlobalContext.load('uri'), filePathUri, async (err: number) => {
284          if (err !== 0) {
285            fs.unlinkSync(filePath);
286            HiLog.error(TAG, `recoverDLPFile: ${this.srcFileName}, failed: ${err}`);
287            let errorInfo =
288              {'title': '', 'msg': $r('app.string.MESSAGE_RECOVER_DLP_ERROR') } as Record<string, string | Resource>;
289            this.showErrorDialog(errorInfo.title, errorInfo.msg);
290            await this.catchProcess();
291            reject();
292          }
293          resolve();
294        });
295      })
296    } catch {
297      return;
298    }
299    this.changeToGenDlpFileHome(filePathUri, filePath);
300  }
301
302  stopFuseLinkHome() {
303    return new Promise<void>((resolve, reject) => {
304      this.homeFeature.stopFuseLinkHome(GlobalContext.load('uri'), (err: number) => {
305        if (err !== 0) {
306          HiLog.error(TAG, `stopFuseLink failed: ${err}`);
307          this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR'));
308          this.processing = false;
309          reject();
310        }
311        resolve();
312      });
313    })
314  }
315
316  changeToGenDlpFileHome(filePathUri: string, filePath: string) {
317    let _dlp = this.tempData();
318    this.homeFeature.genDlpFileHome(filePathUri, GlobalContext.load('uri'), _dlp, async(err: number) => {
319      if (err !== 0) {
320        HiLog.error(TAG, `generateDLPFile failed: ${err}`);
321        fs.unlinkSync(filePath);
322        let errorInfo =
323          {'title': '', 'msg': $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR') } as Record<string, string | Resource>;
324        this.showErrorDialog(errorInfo.title, errorInfo.msg);
325        await this.catchProcess();
326      } else {
327        if (GlobalContext.load('requestIsFromSandBox') as boolean) {
328          this.homeFeature.replaceDLPLinkFileHome(GlobalContext.load('uri'), this.linkFileName, (err: number) => {
329            if (err !== 0) {
330              HiLog.error(TAG, `replaceDLPLinkFile failed: ${err}`);
331            }
332          });
333        }
334        fs.unlinkSync(filePath);
335        await this.catchProcess();
336        this.processing = false;
337        GlobalContext.store('dlpFileName', this.srcFileName);
338        GlobalContext.store('dlpProperty', _dlp);
339        sendDlpManagerFileConfiguration();
340        router.replaceUrl({
341          url: 'pages/encryptionSuccess',
342          params: {
343            staffDataArrayReadOnly: this.staffDataArrayReadOnly,
344            staffDataArrayEdit: this.staffDataArrayEdit,
345            selectedPermissionTypeReadOnly: this.selectedPermissionTypeReadOnly,
346            selectedPermissionTypeEdit: this.selectedPermissionTypeEdit,
347          }
348        })
349      }
350    });
351  }
352
353  async beginEncrypt() {
354    this.processing = true;
355    HiLog.info(TAG, `begin encryption for: ${this.srcFileName}`);
356    let uri: string = '';
357    let displayName: string = this.srcFileName;
358    await this.setUserStat();
359    try {
360      let srcFileUri: string = GlobalContext.load('uri');
361      let srcFileMsg: FileMsg = FileUtils.getSuffixFileMsgByUri(srcFileUri);
362      let srcFileSize: number = await getFileSizeByUri(srcFileUri);
363      AppStorage.setOrCreate('hiFileSize', srcFileSize);
364      AppStorage.setOrCreate('hiFileType', srcFileMsg.fileType);
365      let documentSaveOptions = new picker.DocumentSaveOptions();
366      displayName = displayName + '.dlp';
367      documentSaveOptions.newFileNames = [decodeURIComponent(srcFileMsg.fileName)];
368      documentSaveOptions.fileSuffixChoices = [srcFileMsg.fileType + '.dlp'];
369      documentSaveOptions.defaultFilePathUri = srcFileUri.substring(0,
370        srcFileUri.length - srcFileMsg.fileType.length - srcFileMsg.fileName.length);
371      let documentPicker = new picker.DocumentViewPicker();
372      documentPicker.save(documentSaveOptions).then(async (saveRes) => {
373        if (saveRes === undefined || saveRes.length === 0) {
374          HiLog.error(TAG, `fail to get uri`);
375          this.processing = false;
376          return;
377        }
378        HiLog.info(TAG, `get uri success`);
379        uri = saveRes[0];
380        let uriInfo: fileUri.FileUri = new fileUri.FileUri('');
381        try {
382          uriInfo = new fileUri.FileUri(uri);
383        } catch (err) {
384          HiLog.info(TAG, `fileUri fail: ${JSON.stringify(err)}`);
385        }
386        this.beginToGenDlpFileHome(srcFileUri, uri, uriInfo);
387      }).catch((err: BusinessError) => {
388        HiLog.error(TAG, `DocumentViewPicker save failed: ${JSON.stringify(err)}`);
389        let errorInfo = GetAlertMessage.getAlertMessage(err, $r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR'));
390        this.showErrorDialog(errorInfo.title, errorInfo.msg);
391        this.processing = false;
392        return;
393      });
394    } catch (err) {
395      HiLog.error(TAG, `DocumentViewPicker failed: ${JSON.stringify(err)}`);
396      this.processing = false;
397      return;
398    }
399  }
400
401  beginToGenDlpFileHome(srcFileUri: string, uri: string, uriInfo: fileUri.FileUri) {
402    let _dlp = this.tempData();
403    this.homeFeature.genDlpFileHome(srcFileUri, uri, _dlp, async (err: number) => {
404      if (err !== 0) {
405        if (err === 100) {
406          this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR'));
407          this.processing = false;
408          return;
409        }
410        try {
411          await fs.unlink(uriInfo.path);
412        } catch (err) {
413          HiLog.info(TAG, `unlink fail: ${JSON.stringify(err)}`);
414        }
415        await this.sendDlpFileCreateFault(102, (err.toString())); // 102: DLP_FILE_CREATE_ERROR
416        let errorInfo =
417          {'title': '', 'msg': $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR') } as Record<string, string | Resource>;
418        this.showErrorDialog(errorInfo.title, errorInfo.msg);
419        this.processing = false;
420        return;
421      } else {
422        await this.sendDlpFileCreateEvent(201); // 201: DLP_FILE_CREATE_SUCCESS
423        let dstFileSize: number = await getFileSizeByUri(uri);
424        AppStorage.setOrCreate('hiPolicySizeEnc', dstFileSize);
425        AppStorage.setOrCreate('hiCode', 201);
426        sendDlpFileCreateProperties(dlpPermission.AccountType.DOMAIN_ACCOUNT); // 201: DLP_FILE_CREATE_SUCCESS
427        GlobalContext.store('dlpFileName', uriInfo.name);
428        GlobalContext.store('dlpProperty', _dlp);
429        GlobalContext.store('uri', uri);
430        this.processing = false;
431        sendDlpManagerFileConfiguration();
432        router.replaceUrl({
433          url: 'pages/encryptionSuccess',
434          params: {
435            staffDataArrayReadOnly: this.staffDataArrayReadOnly,
436            staffDataArrayEdit: this.staffDataArrayEdit,
437            selectedPermissionTypeReadOnly: this.selectedPermissionTypeReadOnly,
438            selectedPermissionTypeEdit: this.selectedPermissionTypeEdit,
439          }
440        })
441      }
442    });
443  }
444
445  tempData() {
446    let accountInfo: osAccount.OsAccountInfo = GlobalContext.load('accountInfo');
447    let property: dlpPermission.DLPProperty = GlobalContext.load('dlpProperty') !==
448      undefined ? GlobalContext.load('dlpProperty') : defaultDlpProperty;
449    this.staffDataArrayReadOnly = removeDuplicate(this.staffDataArrayReadOnly, 'authAccount');
450    this.staffDataArrayEdit = removeDuplicate(this.staffDataArrayEdit, 'authAccount');
451    this.staffDataArrayReadOnly = this.staffDataArrayReadOnly.filter((item) => 
452      !this.staffDataArrayEdit.some((ele) => ele.authAccount === item.authAccount)
453    );
454    property.ownerAccount = accountInfo.domainInfo.accountName;
455    property.ownerAccountID = accountInfo.domainInfo.accountId ?? '';
456    property.authUserList = [];
457    property.everyoneAccessList = [];
458    property.offlineAccess = this.selectedIndex === 0 ? true : false;
459    property.expireTime = this.selectedIndex === 0 ? 0 : this.reconfigurationTime(new Date(this.validity)).getTime();
460    if (this.selectedPermissionTypeEdit.data === 'all') {
461      property.everyoneAccessList = [dlpPermission.DLPFileAccess.CONTENT_EDIT];
462      this.staffDataArrayReadOnly = [];
463      this.staffDataArrayEdit = [];
464    } else {
465      this.propertyAddData(property);
466    }
467    let authUserListNew: IAuthUser[] = [];
468    property.authUserList.forEach(item => {
469      authUserListNew.push(
470        new IAuthUser(
471          item.authAccount,
472          item.authAccountType,
473          item.dlpFileAccess,
474          item.permExpiryTime
475        )
476      )
477    })
478    let _dlp = new IDLDLPProperty(
479      property.ownerAccount,
480      property.ownerAccountID,
481      property.ownerAccountType,
482      authUserListNew,
483      property.contactAccount,
484      property.offlineAccess,
485      property.everyoneAccessList,
486      property.expireTime
487    );
488    return _dlp;
489  }
490
491  propertyAddData(property: dlpPermission.DLPProperty) {
492    let isReadyOnlyAll = this.selectedPermissionTypeReadOnly.data === 'all';
493    if (isReadyOnlyAll) {
494      property.everyoneAccessList = [dlpPermission.DLPFileAccess.READ_ONLY];
495    }
496    if (this.selectedPermissionTypeReadOnly.data === 'all') {
497      this.staffDataArrayReadOnly = []
498    }
499    if (['all', 'self'].includes(this.selectedPermissionTypeEdit.data)) {
500      this.staffDataArrayEdit = [];
501    }
502    this.staffDataArrayReadOnly && this.staffDataArrayReadOnly.forEach(item => {
503      property.authUserList?.push({
504        authAccount: item.authAccount,
505        dlpFileAccess: dlpPermission.DLPFileAccess.READ_ONLY,
506        permExpiryTime: Date.UTC(9999, 1, 1),
507        authAccountType: dlpPermission.AccountType.DOMAIN_ACCOUNT,
508      })
509    })
510    this.staffDataArrayEdit && this.staffDataArrayEdit.forEach(item => {
511      property.authUserList?.push({
512        authAccount: item.authAccount,
513        dlpFileAccess: dlpPermission.DLPFileAccess.CONTENT_EDIT,
514        permExpiryTime: Date.UTC(9999, 1, 1),
515        authAccountType: dlpPermission.AccountType.DOMAIN_ACCOUNT,
516      })
517    })
518  }
519
520  async prepareDlpProperty() {
521    let accountInfo: osAccount.OsAccountInfo = GlobalContext.load('accountInfo') as osAccount.OsAccountInfo;
522    this.dlpProperty.ownerAccount = accountInfo.domainInfo.accountName;
523    this.dlpProperty.contactAccount = accountInfo.domainInfo.accountName;
524    this.dlpProperty.ownerAccountID = accountInfo.domainInfo.accountId ?? '';
525    let ownerAccount: dlpPermission.AuthUser = {
526      authAccount: this.dlpProperty.ownerAccount,
527      dlpFileAccess: dlpPermission.DLPFileAccess.FULL_CONTROL,
528      permExpiryTime: Date.UTC(9999, 1, 1),
529      authAccountType: dlpPermission.AccountType.DOMAIN_ACCOUNT,
530    }
531    this.dlpProperty.authUserList?.push(ownerAccount)
532    return
533  }
534
535  async showData(defaultDlpProperty: dlpPermission.DLPProperty) {
536    let routerParams: Record<string, AuthAccount[]> = router.getParams() as Record<string, AuthAccount[]>;
537    this.permissionDict.forEach(async (item, index) => {
538      this.permissionDict[index].value =
539        $r(await getContext(this).resourceManager.getStringValue(item.value.id))
540    })
541    let readOnlyData: dlpPermission.AuthUser[] =
542      defaultDlpProperty.authUserList?.filter((item: dlpPermission.AuthUser) => {
543      return item.dlpFileAccess === 1;
544    }) ?? []
545    let editData: dlpPermission.AuthUser[] = defaultDlpProperty.authUserList?.filter((item: dlpPermission.AuthUser) => {
546      return item.dlpFileAccess === 2;
547    }) ?? []
548    const filterEditFilter = () => {
549      if (editData.length === 0) {
550        this.selectedPermissionTypeEdit = this.permissionDict[2];
551      } else {
552        this.staffDataArrayEdit = routerParams.staffDataArrayEdit as AuthAccount[];
553      }
554    }
555    if ((defaultDlpProperty.everyoneAccessList !== undefined) && (defaultDlpProperty.everyoneAccessList.length > 0)) {
556      let perm = Math.max(...defaultDlpProperty.everyoneAccessList);
557      if (perm === dlpPermission.DLPFileAccess.CONTENT_EDIT) {
558        this.selectedPermissionTypeEdit = this.permissionDict[1];
559        this.staffDataArrayReadOnly = readOnlyData;
560      } else if (perm === dlpPermission.DLPFileAccess.READ_ONLY) {
561        this.selectedPermissionTypeReadOnly = this.permissionDict[1];
562        this.staffDataArrayReadOnly = [];
563        filterEditFilter()
564      }
565    } else {
566      this.staffDataArrayReadOnly = routerParams.staffDataArrayReadOnly as AuthAccount[];
567      filterEditFilter()
568    }
569  }
570
571  async checkAccount() {
572    try {
573      GlobalContext.store('accountInfo', await getOsAccountInfo());
574    } catch (err) {
575      HiLog.error(TAG, `getOsAccountInfo failed: ${JSON.stringify(err)}`);
576      if (this.session !== undefined) {
577        let errorInfo = GetAlertMessage.getAlertMessage({ code: Constants.ERR_JS_GET_ACCOUNT_ERROR } as BusinessError);
578        this.showErrorDialog(errorInfo.title, errorInfo.msg);
579      }
580      return;
581    }
582    let codeMessage = checkDomainAccountInfo(GlobalContext.load('accountInfo') as osAccount.OsAccountInfo);
583    if (codeMessage) {
584      if (this.session !== undefined) {
585        let errorInfo = GetAlertMessage.getAlertMessage(
586          { code: codeMessage } as BusinessError);
587        this.showErrorDialog(errorInfo.title, errorInfo.msg);
588      }
589      return;
590    }
591  }
592
593  reconfigurationTime(date: Date) {
594    let year = date.getFullYear();
595    let month = date.getMonth();
596    let day = date.getDate();
597    return new Date(year, month, day, 23, 59, 59);
598  }
599
600  async aboutToAppear() {
601    this.prepareData = true;
602    await this.checkAccount();
603    AppStorage.setOrCreate('hiAccountVerifySucc', 0);
604    AppStorage.setOrCreate('hiAccountVerifyFail', 0);
605    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
606      HiLog.info(TAG, `encryption request from sandbox`);
607      this.linkFileName = GlobalContext.load('linkFileName') as string;
608      this.srcFileName = GlobalContext.load('dlpFileName') as string;
609      setTimeout(() => {
610        this.showData(GlobalContext.load('dlpProperty'));
611      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
612      this.isDlpFile = true;
613      setTimeout(() => {
614        this.prepareData = false;
615      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
616      return
617    } else {
618      let routerParams = router.getParams();
619      if (routerParams !== undefined) { // is a dlp file
620        HiLog.info(TAG, `encryption request from router`);
621        this.srcFileName = GlobalContext.load('dlpFileName') as string;
622      } else { // not a dlp file
623        HiLog.info(TAG, `encryption request from ability`);
624        this.srcFileName = GlobalContext.load('originFileName') as string;
625      }
626    }
627
628    let isDlpSuffix: boolean = this.srcFileName.endsWith('.dlp');
629    if (!isDlpSuffix) {
630      await this.prepareDlpProperty();
631      this.isDlpFile = false;
632    } else {
633      setTimeout(() => {
634        this.showData(GlobalContext.load('dlpProperty'));
635      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
636      this.isDlpFile = true;
637    }
638    setTimeout(() => {
639      this.prepareData = false;
640    }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
641
642    this.directionStatus = (getContext(this) as common.UIAbilityContext).config.direction ?? -1;
643    directionStatus((counter) => {
644      this.directionStatus = counter;
645    })
646  }
647
648  build() {
649    Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
650      EncryptingPanel({ processing: $processing })
651      if (!this.processing) {
652        Column() {
653          Row() {
654            Text($r('app.string.header_title'))
655              .fontWeight(FontWeight.Bold)
656              .fontFamily($r('app.string.typeface'))
657              .fontColor($r('sys.color.ohos_id_color_text_primary'))
658              .fontSize($r('sys.float.ohos_id_text_size_dialog_tittle'))
659              .width(Constants.HEADER_TEXT_WIDTH)
660              .align(Alignment.Start)
661          }
662          .width(Constants.HEADER_COLUMN_WIDTH)
663          .height(Constants.HEADER_COLUMN_HEIGHT)
664          .padding({
665            left: Constants.HEADER_COLUMN_PADDING_LEFT,
666            right: Constants.HEADER_COLUMN_PADDING_RIGHT
667          })
668          .margin({ bottom: Constants.HEADER_COLUMN_MARGIN_BOTTOM });
669
670          Scroll() {
671            Column() {
672              Row() {
673                Text($r('app.string.header_title_list'))
674                  .fontWeight(FontWeight.Regular)
675                  .fontColor($r('sys.color.ohos_id_color_text_secondary'))
676                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
677                  .width(Constants.HEADER_TEXT_WIDTH)
678                  .align(Alignment.Start)
679              }
680              .width(Constants.HEADER_COLUMN_WIDTH)
681              .margin({ bottom: Constants.ENCRYPTION_CHANGE_TIPS_MARGIN_BOTTOM })
682
683              Row() {
684                Text($r('app.string.header_title_readonly'))
685                  .fontWeight(FontWeight.Medium)
686                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
687                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
688                SymbolGlyph($r('sys.symbol.info_circle'))
689                  .fontSize(`${Constants.FOOTER_ROW_PAD_RIGHT}vp`)
690                  .fontColor([$r('sys.color.icon_secondary')])
691                  .margin({
692                    right: SystemUtils.isRTL() ? Constants.AP_TEXT_PAD_RIGHT : Constants.AP_TEXT_PAD_LEFT,
693                    left: SystemUtils.isRTL() ? Constants.AP_TEXT_PAD_LEFT : Constants.AP_TEXT_PAD_RIGHT,
694                  })
695                  .onClick(() => {
696                    this.handlePopupReadOnly = !this.handlePopupReadOnly
697                  })
698                  .draggable(false)
699                  .bindPopup(this.handlePopupReadOnly, {
700                    builder: this.popupBuilderReadOnly,
701                    placement: SystemUtils.isRTL() ? Placement.BottomRight : Placement.BottomLeft,
702                    offset: { x: SystemUtils.isRTL() ? Constants.POPUP_OFFSET_RTL_X : Constants.POPUP_OFFSET_X },
703                    enableArrow: true,
704                    showInSubWindow: false,
705                    onStateChange: (e) => {
706                      if (!e.isVisible) {
707                        this.handlePopupReadOnly = false
708                      }
709                    }
710                  })
711                Blank()
712                permissionTypeSelect({
713                  selectedItem: $selectedPermissionTypeReadOnly,
714                  staffArray: $staffDataArrayReadOnly,
715                  isDisable: this.selectedPermissionTypeEdit?.data === 'all',
716                  isReadType: true
717                })
718              }
719              .width(Constants.FOOTER_ROW_WIDTH)
720              .margin({
721                top: Constants.ENCRYPTION_SUCCESS_ADD_STAFF_MARGIN_TOP,
722                bottom: Constants.ENCRYPTION_SUCCESS_ADD_STAFF_MARGIN_BOTTOM
723              })
724
725              Row() {
726                if (!['all', 'self'].includes(this.selectedPermissionTypeReadOnly?.data ?? '')) {
727                  AddStaff({
728                    isAccountCheckSuccess: $isAccountCheckSuccess,
729                    staffArray: $staffDataArrayReadOnly,
730                    isDisable: this.selectedPermissionTypeEdit?.data === 'all',
731                  })
732                }
733              }
734              .margin({ bottom: Constants.ENCRYPTION_STAFF_ITEM_MARGIN_BOTTOM })
735
736              Row() {
737                Text($r('app.string.header_title_edit'))
738                  .fontWeight(FontWeight.Medium)
739                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
740                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
741                SymbolGlyph($r('sys.symbol.info_circle'))
742                  .fontSize(`${Constants.FOOTER_ROW_PAD_RIGHT}vp`)
743                  .fontColor([$r('sys.color.icon_secondary')])
744                  .margin({
745                    right: SystemUtils.isRTL() ? Constants.AP_TEXT_PAD_RIGHT : Constants.AP_TEXT_PAD_LEFT,
746                    left: SystemUtils.isRTL() ? Constants.AP_TEXT_PAD_LEFT : Constants.AP_TEXT_PAD_RIGHT,
747                  })
748                  .onClick(() => {
749                    this.handlePopupEdit = !this.handlePopupEdit
750                  })
751                  .draggable(false)
752                  .bindPopup(this.handlePopupEdit, {
753                    builder: this.popupBuilderEdit,
754                    placement: SystemUtils.isRTL() ? Placement.BottomRight : Placement.BottomLeft,
755                    offset: { x: SystemUtils.isRTL() ? Constants.POPUP_OFFSET_RTL_X : Constants.POPUP_OFFSET_X },
756                    enableArrow: true,
757                    showInSubWindow: false,
758                    onStateChange: (e) => {
759                      if (!e.isVisible) {
760                        this.handlePopupEdit = false
761                      }
762                    }
763                  })
764                Blank()
765                permissionTypeSelect({
766                  selectedItem: $selectedPermissionTypeEdit,
767                  staffArray: $staffDataArrayEdit,
768                  isDisable: false,
769                  isReadType: false
770                })
771              }
772              .width(Constants.FOOTER_ROW_WIDTH)
773              .margin({
774                top: Constants.ENCRYPTION_SUCCESS_ADD_STAFF_MARGIN_TOP,
775                bottom: Constants.ENCRYPTION_SUCCESS_ADD_STAFF_MARGIN_BOTTOM
776              })
777
778              Row() {
779                if (!['all', 'self'].includes(this.selectedPermissionTypeEdit?.data ?? '')) {
780                  AddStaff({
781                    isAccountCheckSuccess: $isAccountCheckSuccess,
782                    staffArray: $staffDataArrayEdit,
783                    isDisable: false
784                  })
785                }
786              }
787              .margin({ bottom: Constants.ENCRYPTION_STAFF_ITEM_MARGIN_BOTTOM })
788
789              Row() {
790                Text($r('app.string.Document_valid_until'))
791                  .fontWeight(FontWeight.Medium)
792                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
793                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
794                Blank()
795                if (this.selectedIndex === 1) {
796                  CalendarPicker({ selected: new Date(this.validity) })
797                    .onChange((value) => {
798                      this.validity = value;
799                    })
800                  Row() {
801                    SymbolGlyph($r('sys.symbol.arrowtriangle_down_fill'))
802                      .fontSize(`${Constants.VALIDITY_IMAGE_WIDTH}vp`)
803                      .fontColor([$r('sys.color.ohos_id_color_tertiary')])
804                  }
805                  .height(Constants.VALIDITY_IMAGE_HEIGHT)
806                  .padding({
807                    right: Constants.VALIDITY_IMAGE_PADDING_RIGHT,
808                    left: Constants.VALIDITY_IMAGE_PADDING_LEFT
809                  })
810                  .bindMenu(this.MenuBuilder, { placement: Placement.BottomRight, showInSubWindow: false })
811                } else {
812                  validDateTypeMenu({
813                    selectedIndex: $selectedIndex,
814                    isDisable: false,
815                  })
816                }
817              }
818              .width(Constants.FOOTER_ROW_WIDTH)
819              .margin({
820                top: Constants.ENCRYPTION_SUCCESS_ADD_STAFF_MARGIN_TOP,
821                bottom: Constants.ENCRYPTION_SUCCESS_ADD_STAFF_MARGIN_BOTTOM
822              })
823            }
824          }.constraintSize({
825            maxHeight: this.directionStatus ===
826              0 ? Constants.CHANGE_MAX_HEIGHT : Constants.ENCRYPTION_SUCCESS_MAX_HEIGHT
827          })
828          .padding({
829            left: Constants.HEADER_COLUMN_PADDING_LEFT,
830            right: Constants.HEADER_COLUMN_PADDING_RIGHT
831          })
832
833          Flex({ direction: FlexDirection.Row }) {
834            Button($r('app.string.ban'), { type: ButtonType.Capsule, stateEffect: true })
835              .backgroundColor($r('sys.color.ohos_id_color_button_normal'))
836              .width(Constants.HEADER_TEXT_WIDTH)
837              .focusable(true)
838              .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
839              .controlSize(ControlSize.NORMAL)
840              .onClick(async (event) => {
841                if (this.isDlpFile && !(GlobalContext.load('requestIsFromSandBox') as boolean)) {
842                  this.homeFeature.closeDLPFileHome(GlobalContext.load('uri'), (err: number) => {
843                    if (err !== 0) {
844                      HiLog.error(TAG, `closeDLPFile failed: ${err}`);
845                    }
846                  });
847                }
848                if (this.session !== undefined) {
849                  this.session.terminateSelfWithResult({
850                    'resultCode': 0,
851                    'want': {
852                      'bundleName': Constants.DLP_MANAGER_BUNDLE_NAME,
853                    },
854                  });
855                } else {
856                  if (GlobalContext.load('fileOpenHistoryFromMain')) {
857                    (GlobalContext.load('fileOpenHistoryFromMain') as Map<string, Object>).delete(GlobalContext.load('uri') as string)
858                  }
859                  abilityResult.resultCode = 0;
860                  (getContext(this) as common.UIAbilityContext).terminateSelfWithResult(abilityResult);
861                }
862              })
863              .margin({
864                right: SystemUtils.isRTL() ?
865                  Constants.ADD_STAFF_ITEM_MARGIN_LEFT : Constants.ENCRYPTION_PROTECTION_BUTTON_MARGIN,
866                left: SystemUtils.isRTL() ?
867                  Constants.ENCRYPTION_PROTECTION_BUTTON_MARGIN : Constants.ADD_STAFF_ITEM_MARGIN_LEFT,
868              })
869            Button($r('app.string.sure'), { type: ButtonType.Capsule, stateEffect: true })
870              .backgroundColor($r('sys.color.ohos_id_color_button_normal'))
871              .width(Constants.HEADER_TEXT_WIDTH)
872              .focusable(true)
873              .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
874              .enabled(
875                this.isAccountCheckSuccess &&
876                (this.staffDataArrayReadOnly.length > 0 ||
877                this.staffDataArrayEdit.length > 0 ||
878                ['all', 'self'].includes(this.selectedPermissionTypeReadOnly.data ?? '') ||
879                ['all', 'self'].includes(this.selectedPermissionTypeEdit.data ?? ''))
880              )
881              .controlSize(ControlSize.NORMAL)
882              .onClick(async (event) => {
883                AppStorage.setOrCreate('hiValidDate', false);
884                if (this.selectedIndex === 1) {
885                  let currentTime = new Date().getTime();
886                  let validity = this.reconfigurationTime(new Date(this.validity)).getTime();
887                  if (currentTime >= validity) {
888                    this.showErrorDialogNoTitle($r('app.string.Timeout_is_not_supported'));
889                    return;
890                  }
891                  AppStorage.setOrCreate('validity', this.reconfigurationTime(new Date(this.validity)));
892                  AppStorage.setOrCreate('hiValidDate', true);
893                }
894                AppStorage.setOrCreate('permanent', this.selectedIndex ? false : true);
895                AppStorage.setOrCreate('hiAdvancedSettings', false);
896                AppStorage.setOrCreate('hiStorePath', false);
897                if (this.isDlpFile) {
898                  AppStorage.setOrCreate('hiOperation', 'Change_policy');
899                  await this.changeEncrypt();
900                } else {
901                  AppStorage.setOrCreate('hiOperation', 'Pack_policy');
902                  await this.beginEncrypt();
903                }
904              })
905              .margin({
906                right: SystemUtils.isRTL() ?
907                  Constants.ENCRYPTION_PROTECTION_BUTTON_MARGIN : Constants.ADD_STAFF_ITEM_MARGIN_LEFT,
908                left: SystemUtils.isRTL() ?
909                  Constants.ADD_STAFF_ITEM_MARGIN_LEFT : Constants.ENCRYPTION_PROTECTION_BUTTON_MARGIN,
910              })
911          }
912          .margin({
913            left: Constants.ENCRYPTION_BUTTON_TO_BUTTON_WIDTH,
914            right: Constants.ENCRYPTION_BUTTON_TO_BUTTON_WIDTH,
915            bottom: Constants.ENCRYPTION_BUTTON_MARGIN_BOTTOM,
916            top: Constants.ENCRYPTION_BUTTON_TO_BUTTON_WIDTH
917          })
918        }
919        .visibility(this.processing ? Visibility.Hidden : Visibility.Visible)
920        .width(Constants.ENCRYPTION_PC_FIXING_WIDTH)
921        .backgroundColor($r('sys.color.ohos_id_color_dialog_bg'))
922        .borderRadius($r('sys.float.ohos_id_corner_radius_dialog'))
923        .constraintSize({minWidth: Constants.ENCRYPTION_PC_FIXING_WIDTH})
924        .backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK);
925      }
926    }
927  }
928}
929
930let storage = LocalStorage.getShared();
931@Entry(storage)
932@Component
933struct encryptionProtection {
934  aboutToAppear() {
935  }
936
937  build() {
938    GridRow({
939      columns: {
940        xs: Constants.XS_COLUMNS,
941        sm: Constants.SM_COLUMNS,
942        md: Constants.MD_COLUMNS,
943        lg: Constants.LG_COLUMNS
944      },
945      gutter: Constants.DIALOG_GUTTER
946    }) {
947      GridCol({
948        span: {
949          xs: Constants.XS_SPAN,
950          sm: Constants.SM_SPAN,
951          md: Constants.DIALOG_MD_SPAN,
952          lg: Constants.DIALOG_LG_SPAN
953        },
954        offset: {
955          xs: Constants.XS_OFFSET,
956          sm: Constants.SM_OFFSET,
957          md: Constants.DIALOG_MD_OFFSET,
958          lg: Constants.DIALOG_LG_OFFSET
959        }
960      }) {
961        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center,
962          direction: FlexDirection.Column }) {
963          DlpDialog()
964        }
965      }
966    }
967    .backgroundColor($r('sys.color.mask_fourth'))
968  }
969}
970