From 48ffe7c854ce44dabaf60509dcee7b0476d4a3d9 Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Mon, 2 Dec 2024 18:07:13 +0530 Subject: [PATCH 01/10] empty commit to push --- app/App/HomeController.php | 7 + app/Entities/Controllers/PageController.php | 58 +++++ app/Entities/Models/Page.php | 2 +- app/Entities/Queries/PageQueries.php | 2 +- app/Entities/Repos/BaseRepo.php | 6 +- app/Entities/Repos/PageRepo.php | 37 +++ app/Permissions/Models/EntityPermission.php | 2 +- app/Search/SearchRunner.php | 3 + .../2024_11_25_123200_add_new_permissions.php | 49 ++++ ...80138_add_is_encrypted_column_in_pages.php | 31 +++ lang/en/common.php | 3 + resources/icons/encrypt.svg | 4 + resources/icons/shield-lock.svg | 4 + resources/icons/shield-unlock.svg | 6 + resources/icons/unlock.svg | 4 + resources/js/components/custom-checkbox.js | 1 + .../js/components/encrypt-decrypt-manager.js | 237 ++++++++++++++++++ resources/js/components/index.js | 1 + resources/sass/styles.scss | 4 + .../views/common/confirm-dialog.blade.php | 2 +- resources/views/entities/list-item.blade.php | 7 +- .../pages/parts/editor-toolbox.blade.php | 3 + .../views/pages/parts/list-item.blade.php | 4 + .../views/pages/parts/page-display.blade.php | 14 +- resources/views/pages/show.blade.php | 39 ++- .../parts/asset-permissions-row.blade.php | 10 +- .../views/settings/roles/parts/form.blade.php | 3 +- .../related-asset-permissions-row.blade.php | 4 +- routes/web.php | 8 + 29 files changed, 540 insertions(+), 15 deletions(-) create mode 100644 database/migrations/2024_11_25_123200_add_new_permissions.php create mode 100755 database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php create mode 100644 resources/icons/encrypt.svg create mode 100644 resources/icons/shield-lock.svg create mode 100644 resources/icons/shield-unlock.svg create mode 100644 resources/icons/unlock.svg create mode 100644 resources/js/components/encrypt-decrypt-manager.js diff --git a/app/App/HomeController.php b/app/App/HomeController.php index 0585e0af5cc..3beaa4e9964 100644 --- a/app/App/HomeController.php +++ b/app/App/HomeController.php @@ -43,9 +43,16 @@ public function index( $recents = $this->isSignedIn() ? $recentlyViewed->run(12 * $recentFactor, 1) : $this->queries->books->visibleForList()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get(); + $recents = $recents->filter(function($recent){ + if($recent instanceof Page) { + return !$recent->is_encrypted; + } + return true; + }); $favourites = $topFavourites->run(6); $recentlyUpdatedPages = $this->queries->pages->visibleForList() ->where('draft', false) + ->where('is_encrypted',false) ->orderBy('updated_at', 'desc') ->take($favourites->count() > 0 ? 5 : 10) ->get(); diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index eab53bb2510..8b14c634150 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -23,6 +23,7 @@ use Exception; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Hash; use Illuminate\Validation\ValidationException; use Throwable; @@ -222,6 +223,12 @@ public function update(Request $request, string $bookSlug, string $pageSlug) $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); + if($page->is_decrypt == 1) + { + $request['html'] = encrypt($request['html']); + $request['is_decrypt'] = false; + } + $this->pageRepo->update($page, $request->all()); return redirect($page->getUrl()); @@ -467,4 +474,55 @@ public function copy(Request $request, Cloner $cloner, string $bookSlug, string return redirect($pageCopy->getUrl()); } + + public function encrypt(Request $request,string $bookSlug, string $pageSlug) + { + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); + return $this->pageRepo->encryptPageContent($request->all(),$page); + } + + public function decrypt(Request $request,string $bookSlug, string $pageSlug) + { + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); + return $this->pageRepo->decryptPageContent($request->all(),$page); + // if($page->is_encrypted) + // { + // if(Hash::check($request->get('decrypt_password'),$page->decrypt_password)) + // { + // return $this->pageRepo->decryptPageContent($request->all(),$page); + // } + // else + // { + // return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); + // } + // } + } + + public function updateEncryption(Request $request,string $bookSlug, string $pageSlug) + { + $this->validate($request,[ + 'html' => ['required'], + 'decrypt_password' => ['required'], + 'is_encrypted' => ['required','boolean'], + ]); + + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); + $this->pageRepo->update($page, $request->all()); + return response()->json(['message' => 'Encryption Update SuccessFully','success' => true]); + + } + + public function updateDecryption(Request $request,string $bookSlug, string $pageSlug) + { + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); + if(Hash::check($request->get('decrypt_password'),$page->decrypt_password)) + { + $this->pageRepo->update($page, $request->all()); + return response()->json(['contents' => [],'message' => 'Decryption Update SuccessFully','success' => true]); + } + else + { + return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); + } + } } diff --git a/app/Entities/Models/Page.php b/app/Entities/Models/Page.php index 499ef4d7288..b8180f133e6 100644 --- a/app/Entities/Models/Page.php +++ b/app/Entities/Models/Page.php @@ -33,7 +33,7 @@ class Page extends BookChild { use HasFactory; - protected $fillable = ['name', 'priority']; + protected $fillable = ['name', 'priority','is_encrypted','decrypt_password','is_decrypt']; public string $textField = 'text'; public string $htmlField = 'html'; diff --git a/app/Entities/Queries/PageQueries.php b/app/Entities/Queries/PageQueries.php index 06298f470b9..5035776dcbc 100644 --- a/app/Entities/Queries/PageQueries.php +++ b/app/Entities/Queries/PageQueries.php @@ -15,7 +15,7 @@ class PageQueries implements ProvidesEntityQueries ]; protected static array $listAttributes = [ 'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', - 'template', 'text', 'created_at', 'updated_at', 'priority', 'owned_by', + 'template', 'text', 'created_at', 'updated_at', 'priority', 'owned_by', 'is_encrypted', ]; public function start(): Builder diff --git a/app/Entities/Repos/BaseRepo.php b/app/Entities/Repos/BaseRepo.php index 033350743e0..f964aa8852f 100644 --- a/app/Entities/Repos/BaseRepo.php +++ b/app/Entities/Repos/BaseRepo.php @@ -8,6 +8,7 @@ use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\HasCoverImage; use BookStack\Entities\Models\HasHtmlDescription; +use BookStack\Entities\Models\Page; use BookStack\Entities\Queries\PageQueries; use BookStack\Exceptions\ImageUploadException; use BookStack\References\ReferenceStore; @@ -75,7 +76,10 @@ public function update(Entity $entity, array $input) } $entity->rebuildPermissions(); - $entity->indexForSearch(); + if((array_key_exists('is_encrypted',$input) && $input['is_encrypted'] == true) || !(($entity InstanceOf Page) && $entity->is_encrypted == true)) + { + $entity->indexForSearch(); + } $this->referenceStore->updateForEntity($entity); if ($oldUrl !== $entity->getUrl()) { diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 1bc15392cec..29b2e4dd5bf 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -19,6 +19,8 @@ use BookStack\References\ReferenceStore; use BookStack\References\ReferenceUpdater; use Exception; +use Illuminate\Support\Facades\Hash; +use Str; class PageRepo { @@ -97,6 +99,12 @@ public function update(Page $page, array $input): Page $oldName = $page->name; $oldMarkdown = $page->markdown; + //Make Hashable decrypt Password + if(array_key_exists('decrypt_password',$input)) + { + $input['decrypt_password'] = Hash::make($input['decrypt_password']); + } + $this->updateTemplateStatusAndContentFromInput($page, $input); $this->baseRepo->update($page, $input); @@ -279,4 +287,33 @@ protected function getNewPriority(Page $page): int return (new BookContents($page->book))->getLastPriority() + 1; } + + public function encryptPageContent(array $data, Page $page) + { + if(!$page->is_encrypted) + { + $content = encrypt($data['content']); + return response()->json(['content' => $content,'message' => 'Encrypt Content SuccessFully','success' => true]); + } + else + { + return response()->json(['content' => '','message' => 'Already Encrypted','success' => false]); + } + } + + public function decryptPageContent(array $data, Page $page) + { + if($page->is_encrypted) + { + if(Hash::check($data['decrypt_password'],$page->decrypt_password)) + { + $content = decrypt($data['content']); + return response()->json(['content' => $content,'message' => 'Decrypt Content SuccessFully','success' => true]); + } + else + { + return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); + } + } + } } diff --git a/app/Permissions/Models/EntityPermission.php b/app/Permissions/Models/EntityPermission.php index 1ef9c2886f5..63951a82858 100644 --- a/app/Permissions/Models/EntityPermission.php +++ b/app/Permissions/Models/EntityPermission.php @@ -18,7 +18,7 @@ */ class EntityPermission extends Model { - public const PERMISSIONS = ['view', 'create', 'update', 'delete']; + public const PERMISSIONS = ['view', 'create', 'update', 'delete', 'encrypt']; protected $fillable = ['role_id', 'view', 'create', 'update', 'delete']; public $timestamps = false; diff --git a/app/Search/SearchRunner.php b/app/Search/SearchRunner.php index 9716f8053be..9da4aa3b0cd 100644 --- a/app/Search/SearchRunner.php +++ b/app/Search/SearchRunner.php @@ -159,6 +159,9 @@ protected function buildQuery(SearchOptions $searchOpts, string $entityType): El $inputTerm = str_replace('\\', '\\\\', $exact->value); $query->where('name', 'like', '%' . $inputTerm . '%') ->orWhere($entityModelInstance->textField, 'like', '%' . $inputTerm . '%'); + if ($entityModelInstance instanceof Page) { + $query->Where('is_encrypted','!=',1); + } }; $exact->negated ? $entityQuery->whereNot($filter) : $entityQuery->where($filter); diff --git a/database/migrations/2024_11_25_123200_add_new_permissions.php b/database/migrations/2024_11_25_123200_add_new_permissions.php new file mode 100644 index 00000000000..7c1b50ffa66 --- /dev/null +++ b/database/migrations/2024_11_25_123200_add_new_permissions.php @@ -0,0 +1,49 @@ +where('display_name', '=', 'admin')->first()->id; + + // Create & attach new entity permissions + $entities = ['Book', 'Page', 'Chapter', 'bookshelf']; + $ops = ['Restrict All', 'Restrict Own','Encrypt All','Encrypt Own']; + foreach ($entities as $entity) { + foreach ($ops as $op) { + if(($op === 'Encrypt All' || $op === 'Encrypt Own') && $entity !== 'Page'){ + break; + } + $permissionId = DB::table('role_permissions')->insertGetId([ + 'name' => strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op)), + 'display_name' => $op . ' ' . $entity . 's', + 'created_at' => Carbon::now()->toDateTimeString(), + 'updated_at' => Carbon::now()->toDateTimeString(), + ]); + DB::table('permission_role')->insert([ + 'role_id' => $adminRoleId, + 'permission_id' => $permissionId, + ]); + } + } + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php b/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php new file mode 100755 index 00000000000..cea2f229513 --- /dev/null +++ b/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php @@ -0,0 +1,31 @@ +boolean('is_encrypted')->after('priority')->default(false); + $table->boolean('is_decrypt')->after('is_encrypted'); + $table->text('decrypt_password')->after('is_encrypted'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('pages', function (Blueprint $table) { + // + }); + } +}; diff --git a/lang/en/common.php b/lang/en/common.php index b05169bb2c4..9517d41b173 100644 --- a/lang/en/common.php +++ b/lang/en/common.php @@ -53,6 +53,9 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', + 'restrict' => 'Restrict', + 'encrypt' => 'Encrypt', + 'decrypt' => 'Decrypt', // Sort Options 'sort_options' => 'Sort Options', diff --git a/resources/icons/encrypt.svg b/resources/icons/encrypt.svg new file mode 100644 index 00000000000..93c1ff71d93 --- /dev/null +++ b/resources/icons/encrypt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/resources/icons/shield-lock.svg b/resources/icons/shield-lock.svg new file mode 100644 index 00000000000..c425c68711e --- /dev/null +++ b/resources/icons/shield-lock.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/resources/icons/shield-unlock.svg b/resources/icons/shield-unlock.svg new file mode 100644 index 00000000000..954293cfe76 --- /dev/null +++ b/resources/icons/shield-unlock.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/icons/unlock.svg b/resources/icons/unlock.svg new file mode 100644 index 00000000000..3233f3a9e47 --- /dev/null +++ b/resources/icons/unlock.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/resources/js/components/custom-checkbox.js b/resources/js/components/custom-checkbox.js index a5f1d566424..0d732dd895a 100644 --- a/resources/js/components/custom-checkbox.js +++ b/resources/js/components/custom-checkbox.js @@ -27,6 +27,7 @@ export class CustomCheckbox extends Component { stateChange() { const checked = this.checkbox.checked ? 'true' : 'false'; + this.checkbox.value = this.checkbox.checked ? 'true' : 'false'; this.display.setAttribute('aria-checked', checked); } diff --git a/resources/js/components/encrypt-decrypt-manager.js b/resources/js/components/encrypt-decrypt-manager.js new file mode 100644 index 00000000000..25eb708ecf8 --- /dev/null +++ b/resources/js/components/encrypt-decrypt-manager.js @@ -0,0 +1,237 @@ +import {Component} from './component'; + +export class EncryptDecryptManager extends Component +{ + setup() + { + this.container = this.$el; + this.encryptBtn = this.$refs.encryptBtn; + this.decryptSubmitBtn = this.$refs.decryptSubmitBtn; + this.decryptPassword = this.$refs.decryptPasswordInput; + this.editBtn = this.$refs.editBtn; + this.invalidMsg = this.$refs.invalidPassword; + + this.url = this.$opts.url; + this.pageName = this.$opts.pageName; + this.pageIsEncrypted = this.$opts.pageEncrypted; + + this.encryptDialog = document.querySelector('.encrypt-decrypt-dialog'); + this.contentPart = document.querySelector('.page-content'); + this.pageContentPTags = document.querySelector('.page-content').querySelectorAll('p'); + this.pageContent = document.querySelector('.page-content').querySelector('div[dir="auto"]'); + this.pageDetailContent = document.querySelector('.page-content').querySelector('.page-detail-content'); + this.encryptIcon = document.querySelector('.page-content').querySelector('.encrypt-icon') + + this.invalidPassword = this.encryptDialog.querySelector('.invalid-password'); + this.passwordInput = this.encryptDialog.querySelector('#page-encrypt-password'); + + this.is_decrypt = false; + + this.setupListener(); + } + + setupListener() + { + this.encryptBtn.addEventListener("click",async event => { + event.preventDefault(); + const response = await this.openDialog(); + if(response) + { + if(this.pageIsEncrypted == 1) + { + this.decryptContent(this.passwordInput.value,true,false); + } + else + { + this.encryptContent(); + } + } + }); + + if(this.pageIsEncrypted == 1) + { + this.contentPart.addEventListener("mousedown", event => event.preventDefault()); + this.contentPart.addEventListener("selectstart", event => event.preventDefault()); + this.contentPart.addEventListener("copy", event => event.preventDefault()); + this.decryptPassword.addEventListener("input",()=>{this.invalidMsg.classList.add('hidden')}); + this.decryptSubmitBtn.addEventListener("click",()=>this.decryptContent(this.decryptPassword.value)); + this.editBtn.addEventListener("click",event=>this.decryptContentOnEdit(event)); + this.decryptPassword.addEventListener("keydown",event => { + if(event.key == "Enter") + { + this.decryptContent(this.decryptPassword.value); + } + }); + this.passwordInput.addEventListener("input",()=>{ + this.invalidPassword.classList.add("hidden"); + }) + } + } + + encryptContent() + { + const password = this.passwordInput.value; + if(password.length > 6) + { + const contents = this.pageDetailContent.innerHTML; + + window.$http.post(`${this.url}/encrypt`, {content: contents}).then(resp=>{ + if(resp.data.success) + { + // let contents = this.changePageContent(resp.data.contents); + this.pageDetailContent.innerHTML = resp.data.content; + + const data = { + 'html' : resp.data.content, + 'is_encrypted' : true, + 'decrypt_password' : password, + } + this.updateData(data,true,false); + } + }); + } + } + + decryptContent(decryptPassword,updateDecryption = false,forEdit = false) + { + if(decryptPassword.length > 6) + { + + const decryptData = { + content: this.pageDetailContent.innerHTML, + decrypt_password: decryptPassword, + } + if(!this.is_decrypt) + { + window.$http.post(`${this.url}/decrypt`, decryptData).then(async resp=>{ + if(resp.data.success) + { + // let contents = this.changePageContent(resp.data.contents); + this.decryptPassword.value = ""; + this.pageDetailContent.innerHTML = resp.data.content; + + if(updateDecryption) + { + const data = { + 'html' : resp.data.content, + 'is_encrypted' : forEdit, + 'is_decrypt' : forEdit, + 'decrypt_password' : decryptPassword, + }; + this.updateData(data,false,forEdit); + } + else + { + this.is_decrypt = true; + this.encryptIcon.classList.add("hidden"); + this.pageDetailContent.classList.remove("hidden"); + } + } + else + { + if(forEdit || updateDecryption) + { + this.invalidPassword.innerHTML = resp.data.message; + this.invalidPassword.classList.remove("hidden"); + this.openDialog(); + } + else + { + this.invalidMsg.innerHTML = resp.data.message; + this.invalidMsg.classList.remove("hidden"); + } + } + }); + } + else + { + const data = { + 'html' : this.pageDetailContent.innerHTML, + 'is_encrypted' : forEdit, + 'is_decrypt' : forEdit, + 'decrypt_password' : decryptPassword, + }; + this.updateData(data,false,forEdit); + } + + } + } + + async openDialog() + { + this.encryptDialog.querySelector('#page-encrypt-password').value = ''; + const dialog = window.$components.firstOnElement(this.encryptDialog, 'confirm-dialog'); + const response = await dialog.show(); + return response; + } + + async decryptContentOnEdit(event) + { + event.preventDefault(); + const response = await this.openDialog(); + if(response) + { + this.decryptContent(this.encryptDialog.querySelector('#page-encrypt-password').value,true,true); + } + } + + getPageContent() + { + const contents = []; + + this.pageContentPTags.forEach(element => { + contents.push(element.innerHTML); + }); + return contents; + } + + changePageContent(contents) + { + this.pageContentPTags.forEach((element,index) => { + element.innerHTML = contents[index]; + contents[index] = element.outerHTML; + }); + return contents; + } + + async updateData(data,updateEncryption,forEdit) + { + try{ + if(updateEncryption) + { + window.$http.put(`${this.url}/update-encryption`,data).then(resp=> + { + if(resp.data.success){ + window.location.reload(); + } + }); + } + else + { + window.$http.put(`${this.url}/update-decryption`,data).then(resp=> + { + if(resp.data.success){ + if(forEdit) + { + window.location.href = this.editBtn.getAttribute('href'); + } + else + { + window.location.reload(); + } + } + else + { + this.invalidMsg.value = resp.data.message; + this.invalidMsg.classList.remove('hidden'); + } + }); + } + + } + catch(error) + { + console.log(error); + } + } +} \ No newline at end of file diff --git a/resources/js/components/index.js b/resources/js/components/index.js index 8ad5e14cb2e..2d12ebb052e 100644 --- a/resources/js/components/index.js +++ b/resources/js/components/index.js @@ -19,6 +19,7 @@ export {Dropdown} from './dropdown'; export {DropdownSearch} from './dropdown-search'; export {Dropzone} from './dropzone'; export {EditorToolbox} from './editor-toolbox'; +export {EncryptDecryptManager} from './encrypt-decrypt-manager'; export {EntityPermissions} from './entity-permissions'; export {EntitySearch} from './entity-search'; export {EntitySelector} from './entity-selector'; diff --git a/resources/sass/styles.scss b/resources/sass/styles.scss index 636367e3aeb..a95e6ab69b7 100644 --- a/resources/sass/styles.scss +++ b/resources/sass/styles.scss @@ -230,4 +230,8 @@ $loadingSize: 10px; transform: rotate(180deg); } } +} + +.permission-asset-table{ + overflow-y: auto; } \ No newline at end of file diff --git a/resources/views/common/confirm-dialog.blade.php b/resources/views/common/confirm-dialog.blade.php index 736a1c49b7d..7fa4d0601b6 100644 --- a/resources/views/common/confirm-dialog.blade.php +++ b/resources/views/common/confirm-dialog.blade.php @@ -1,7 +1,7 @@ diff --git a/resources/views/pages/parts/list-item.blade.php b/resources/views/pages/parts/list-item.blade.php index 5707a9c6619..ba81d6dec5c 100644 --- a/resources/views/pages/parts/list-item.blade.php +++ b/resources/views/pages/parts/list-item.blade.php @@ -1,5 +1,9 @@ @component('entities.list-item-basic', ['entity' => $page]) +@if($page->is_encrypted) + @icon('lock') +@else

{{ $page->getExcerpt() }}

+@endif @endcomponent \ No newline at end of file diff --git a/resources/views/pages/parts/page-display.blade.php b/resources/views/pages/parts/page-display.blade.php index ba2a2c336fd..91f6deb697f 100644 --- a/resources/views/pages/parts/page-display.blade.php +++ b/resources/views/pages/parts/page-display.blade.php @@ -3,10 +3,14 @@

{{$page->name}}

- - @if (isset($diff) && $diff) - {!! $diff !!} - @else - {!! isset($page->renderedHTML) ? $page->renderedHTML : $page->html !!} + @if($page->is_encrypted) +

@icon('lock')

@endif + \ No newline at end of file diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php index e3a31dd5ebf..ab8bcf6308c 100644 --- a/resources/views/pages/show.blade.php +++ b/resources/views/pages/show.blade.php @@ -78,6 +78,7 @@ class="page-content clearfix"> @stop @section('right') +
{{ trans('common.details') }}
+
@stop + +@component('common.confirm-dialog', ['title' => trans($page->is_encrypted ? 'common.decrypt' : 'common.encrypt'), 'class' => 'encrypt-decrypt-dialog']) +

+ +
+ +

+@endcomponent \ No newline at end of file diff --git a/resources/views/settings/roles/parts/asset-permissions-row.blade.php b/resources/views/settings/roles/parts/asset-permissions-row.blade.php index 8bff570cb85..3a205b3a97f 100644 --- a/resources/views/settings/roles/parts/asset-permissions-row.blade.php +++ b/resources/views/settings/roles/parts/asset-permissions-row.blade.php @@ -1,4 +1,4 @@ -
+
{{ $title }}
{{ trans('common.toggle_all') }} @@ -29,4 +29,12 @@
@include('settings.roles.parts.checkbox', ['permission' => $permissionPrefix . '-delete-all', 'label' => trans('settings.role_all')])
+
+ @if($permissionPrefix === 'page') + {{ trans('common.encrypt') }}
+ @include('settings.roles.parts.checkbox', ['permission' => $permissionPrefix . '-encrypt-own', 'label' => trans('settings.role_own')]) +
+ @include('settings.roles.parts.checkbox', ['permission' => $permissionPrefix . '-encrypt-all', 'label' => trans('settings.role_all')]) + @endif +
\ No newline at end of file diff --git a/resources/views/settings/roles/parts/form.blade.php b/resources/views/settings/roles/parts/form.blade.php index 9fa76f2bfd7..b94e62bd919 100644 --- a/resources/views/settings/roles/parts/form.blade.php +++ b/resources/views/settings/roles/parts/form.blade.php @@ -60,7 +60,7 @@
+ class="item-list toggle-switch-list permission-asset-table">
{{ trans('common.toggle_all') }} @@ -69,6 +69,7 @@ class="item-list toggle-switch-list">
{{ trans('common.view') }}
{{ trans('common.edit') }}
{{ trans('common.delete') }}
+
Encrypt
@include('settings.roles.parts.asset-permissions-row', ['title' => trans('entities.shelves'), 'permissionPrefix' => 'bookshelf']) @include('settings.roles.parts.asset-permissions-row', ['title' => trans('entities.books'), 'permissionPrefix' => 'book']) diff --git a/resources/views/settings/roles/parts/related-asset-permissions-row.blade.php b/resources/views/settings/roles/parts/related-asset-permissions-row.blade.php index 62fdd6b744a..deec9cb46c4 100644 --- a/resources/views/settings/roles/parts/related-asset-permissions-row.blade.php +++ b/resources/views/settings/roles/parts/related-asset-permissions-row.blade.php @@ -1,4 +1,4 @@ -
+
{{ $title }}
{{ trans('common.toggle_all') }} @@ -23,4 +23,6 @@
@include('settings.roles.parts.checkbox', ['permission' => $permissionPrefix . '-delete-all', 'label' => trans('settings.role_all')])
+
+
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 81b938f32ec..781b52ad990 100644 --- a/routes/web.php +++ b/routes/web.php @@ -112,6 +112,14 @@ Route::delete('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/delete', [EntityControllers\PageRevisionController::class, 'destroy']); Route::delete('/page-revisions/user-drafts/{pageId}', [EntityControllers\PageRevisionController::class, 'destroyUserDraft']); + + // Encrypt - Decrypt + Route::post('/books/{bookSlug}/page/{pageSlug}/encrypt', [EntityControllers\PageController::class, 'encrypt']); + Route::post('/books/{bookSlug}/page/{pageSlug}/decrypt', [EntityControllers\PageController::class, 'decrypt']); + Route::put('/books/{bookSlug}/page/{pageSlug}/update-encryption', [EntityControllers\PageController::class, 'updateEncryption']); + Route::put('/books/{bookSlug}/page/{pageSlug}/update-decryption', [EntityControllers\PageController::class, 'updateDecryption']); + + // Chapters Route::get('/books/{bookSlug}/chapter/{chapterSlug}/create-page', [EntityControllers\PageController::class, 'create']); Route::post('/books/{bookSlug}/chapter/{chapterSlug}/create-guest-page', [EntityControllers\PageController::class, 'createAsGuest']); From 724a62f2bdef2fc5845bbc5a8f983585e5f925ad Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Mon, 2 Dec 2024 18:16:08 +0530 Subject: [PATCH 02/10] empty commit to push From dd257dccfbc5511ec7f39d3ce36cd1cb69e1502d Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Wed, 4 Dec 2024 16:13:06 +0530 Subject: [PATCH 03/10] "Added page encryption and decryption functionality, tests, and updates to page display" --- app/Activity/ActivityType.php | 2 + app/Entities/Controllers/PageController.php | 38 +++-- .../Controllers/PageExportController.php | 26 ++- app/Entities/Queries/PageQueries.php | 2 +- app/Entities/Repos/PageRepo.php | 20 ++- app/Entities/Tools/BookContents.php | 6 + app/Entities/Tools/ExportFormatter.php | 22 ++- app/Uploads/ImageService.php | 2 +- database/.gitignore | 0 ...d_encrypt_column_in_entity_permissions.php | 28 ++++ lang/en/activities.php | 4 + resources/js/components/collapsible.js | 2 +- .../js/components/encrypt-decrypt-manager.js | 153 +++++++++--------- .../views/entities/export-menu.blade.php | 3 +- .../views/entities/page-encrypted.blade.php | 35 ++++ .../pages/parts/editor-toolbox.blade.php | 3 - .../views/pages/parts/page-display.blade.php | 7 +- resources/views/pages/show.blade.php | 22 ++- routes/web.php | 2 + tests/Api/ContentPermissionsApiTest.php | 3 + tests/Entity/PageTest.php | 94 +++++++++++ 21 files changed, 356 insertions(+), 118 deletions(-) mode change 100644 => 100755 database/.gitignore create mode 100755 database/migrations/2024_12_03_062042_add_encrypt_column_in_entity_permissions.php create mode 100644 resources/views/entities/page-encrypted.blade.php diff --git a/app/Activity/ActivityType.php b/app/Activity/ActivityType.php index 09b2ae73c56..2a3e674199a 100644 --- a/app/Activity/ActivityType.php +++ b/app/Activity/ActivityType.php @@ -9,6 +9,8 @@ class ActivityType const PAGE_DELETE = 'page_delete'; const PAGE_RESTORE = 'page_restore'; const PAGE_MOVE = 'page_move'; + const PAGE_ENCRYPTED = 'page_encrypted'; + const PAGE_DECRYPTED = 'page_decrypted'; const CHAPTER_CREATE = 'chapter_create'; const CHAPTER_UPDATE = 'chapter_update'; diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index 8b14c634150..be1f2f40e2e 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -199,6 +199,12 @@ public function edit(Request $request, string $bookSlug, string $pageSlug) $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); + if(session()->get('is_decrypt') == 'FOR_EDIT') + { + $page->html = decrypt($page->html); + session()->remove('is_decrypt'); + } + $editorData = new PageEditorData($page, $this->entityQueries, $request->query('editor', '')); if ($editorData->getWarnings()) { $this->showWarningNotification(implode("\n", $editorData->getWarnings())); @@ -223,10 +229,10 @@ public function update(Request $request, string $bookSlug, string $pageSlug) $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); - if($page->is_decrypt == 1) + if($page->is_decrypt == 'FOR_EDIT') { $request['html'] = encrypt($request['html']); - $request['is_decrypt'] = false; + $request['is_decrypt'] = 'NONE'; } $this->pageRepo->update($page, $request->all()); @@ -485,17 +491,6 @@ public function decrypt(Request $request,string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); return $this->pageRepo->decryptPageContent($request->all(),$page); - // if($page->is_encrypted) - // { - // if(Hash::check($request->get('decrypt_password'),$page->decrypt_password)) - // { - // return $this->pageRepo->decryptPageContent($request->all(),$page); - // } - // else - // { - // return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); - // } - // } } public function updateEncryption(Request $request,string $bookSlug, string $pageSlug) @@ -515,14 +510,27 @@ public function updateEncryption(Request $request,string $bookSlug, string $page public function updateDecryption(Request $request,string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); - if(Hash::check($request->get('decrypt_password'),$page->decrypt_password)) + if($this->validateDecryptPassword($request, $bookSlug, $pageSlug)) { + if($request->has('is_decrypt')) + { + session()->put('is_decrypt',$request->get('is_decrypt')); + \Log::info('Update : ' .session()->get('is_decrypt')); + } $this->pageRepo->update($page, $request->all()); - return response()->json(['contents' => [],'message' => 'Decryption Update SuccessFully','success' => true]); + return response()->json(['contents' => [],'message' => 'Decrypted SuccessFully','success' => true]); } else { return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); } } + + public function validateDecryptPassword(Request $request,string $bookSlug, string $pageSlug) + { + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); + return Hash::check($request->get('decrypt_password'),$page->decrypt_password) ? + response()->json(['success'=>true]) : + response()->json(['success'=>false]); + } } diff --git a/app/Entities/Controllers/PageExportController.php b/app/Entities/Controllers/PageExportController.php index be97f1930bd..ac5e1472301 100644 --- a/app/Entities/Controllers/PageExportController.php +++ b/app/Entities/Controllers/PageExportController.php @@ -2,6 +2,7 @@ namespace BookStack\Entities\Controllers; +use BookStack\Entities\Models\Page; use BookStack\Entities\Queries\PageQueries; use BookStack\Entities\Tools\ExportFormatter; use BookStack\Entities\Tools\PageContent; @@ -28,6 +29,7 @@ public function __construct( public function pdf(string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + $this->validatePageEncrypted($page); $page->html = (new PageContent($page))->render(); $pdfContent = $this->exportFormatter->pageToPdf($page); @@ -43,6 +45,7 @@ public function pdf(string $bookSlug, string $pageSlug) public function html(string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + $this->validatePageEncrypted($page); $page->html = (new PageContent($page))->render(); $containedHtml = $this->exportFormatter->pageToContainedHtml($page); @@ -57,7 +60,8 @@ public function html(string $bookSlug, string $pageSlug) public function plainText(string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); - $pageText = $this->exportFormatter->pageToPlainText($page); + $this->validatePageEncrypted($page); + $pageText = $this->exportFormatter->pageToPlainText($page,$page->is_encrypted); return $this->download()->directly($pageText, $pageSlug . '.txt'); } @@ -70,8 +74,28 @@ public function plainText(string $bookSlug, string $pageSlug) public function markdown(string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + $this->validatePageEncrypted($page); $pageText = $this->exportFormatter->pageToMarkdown($page); return $this->download()->directly($pageText, $pageSlug . '.md'); } + + public function validatePageEncrypted(Page $page) + { + + if($page->is_encrypted) + { + if(session()->get('is_decrypt') == 'FOR_EXPORT') + { + $page->html = decrypt($page->html); + session()->put('is_decrypt','NONE'); + return true; + } + else + { + return redirect($page->getUrl()); + } + } + return true; + } } diff --git a/app/Entities/Queries/PageQueries.php b/app/Entities/Queries/PageQueries.php index 5035776dcbc..3f09e061f86 100644 --- a/app/Entities/Queries/PageQueries.php +++ b/app/Entities/Queries/PageQueries.php @@ -11,7 +11,7 @@ class PageQueries implements ProvidesEntityQueries protected static array $contentAttributes = [ 'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'html', 'text', 'created_at', 'updated_at', 'priority', - 'created_by', 'updated_by', 'owned_by', + 'created_by', 'updated_by', 'owned_by', 'is_encrypted', ]; protected static array $listAttributes = [ 'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 29b2e4dd5bf..4991a6cd61a 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -124,7 +124,21 @@ public function update(Page $page, array $input): Page $this->revisionRepo->storeNewForPage($page, $summary); } - Activity::add(ActivityType::PAGE_UPDATE, $page); + if(array_key_exists('is_encrypted',$input)) + { + if($input['is_encrypted'] == true) + { + Activity::add(ActivityType::PAGE_ENCRYPTED, $page); + } + else if($input['is_encrypted'] == false) + { + Activity::add(ActivityType::PAGE_DECRYPTED, $page); + } + } + else if(!array_key_exists('is_decrypt',$input)) + { + Activity::add(ActivityType::PAGE_UPDATE, $page); + } return $page; } @@ -293,7 +307,7 @@ public function encryptPageContent(array $data, Page $page) if(!$page->is_encrypted) { $content = encrypt($data['content']); - return response()->json(['content' => $content,'message' => 'Encrypt Content SuccessFully','success' => true]); + return response()->json(['content' => $content,'message' => 'Encrypted SuccessFully','success' => true]); } else { @@ -308,7 +322,7 @@ public function decryptPageContent(array $data, Page $page) if(Hash::check($data['decrypt_password'],$page->decrypt_password)) { $content = decrypt($data['content']); - return response()->json(['content' => $content,'message' => 'Decrypt Content SuccessFully','success' => true]); + return response()->json(['content' => $content,'message' => 'Decrypted SuccessFully','success' => true]); } else { diff --git a/app/Entities/Tools/BookContents.php b/app/Entities/Tools/BookContents.php index 7fa2134b7fa..5223408ef59 100644 --- a/app/Entities/Tools/BookContents.php +++ b/app/Entities/Tools/BookContents.php @@ -42,6 +42,12 @@ public function getLastPriority(): int public function getTree(bool $showDrafts = false, bool $renderPages = false): Collection { $pages = $this->getPages($showDrafts, $renderPages); + + // Check For Encrypted Pages + $pages->each(function($page){ + $page->html = $page->is_encrypted ? '

This page is encrypted

' : $page->html; + }); + $chapters = $this->book->chapters()->scopes('visible')->get(); $all = collect()->concat($pages)->concat($chapters); $chapterMap = $chapters->keyBy('id'); diff --git a/app/Entities/Tools/ExportFormatter.php b/app/Entities/Tools/ExportFormatter.php index beddfe8e6e0..26fe1531cd4 100644 --- a/app/Entities/Tools/ExportFormatter.php +++ b/app/Entities/Tools/ExportFormatter.php @@ -36,6 +36,7 @@ public function pageToContainedHtml(Page $page): string 'format' => 'html', 'cspContent' => $this->cspService->getCspMetaTagValue(), 'locale' => user()->getLocale(), + 'export' => true, ])->render(); return $this->containHtml($pageHtml); @@ -50,7 +51,7 @@ public function chapterToContainedHtml(Chapter $chapter): string { $pages = $chapter->getVisiblePages(); $pages->each(function ($page) { - $page->html = (new PageContent($page))->render(); + $page->html = $page->is_encrypted ? "

This page is Encrypted

" : (new PageContent($page))->render(); }); $html = view('exports.chapter', [ 'chapter' => $chapter, @@ -95,6 +96,7 @@ public function pageToPdf(Page $page): string 'format' => 'pdf', 'engine' => $this->pdfGenerator->getActiveEngine(), 'locale' => user()->getLocale(), + 'export' => true, ])->render(); return $this->htmlToPdf($html); @@ -109,7 +111,7 @@ public function chapterToPdf(Chapter $chapter): string { $pages = $chapter->getVisiblePages(); $pages->each(function ($page) { - $page->html = (new PageContent($page))->render(); + $page->html = $page->is_encrypted ? "

This page is Encrypted

" : (new PageContent($page))->render(); }); $html = view('exports.chapter', [ @@ -270,6 +272,10 @@ public function chapterToPlainText(Chapter $chapter): string $parts = []; foreach ($chapter->getVisiblePages() as $page) { + if($page->is_encrypted) + { + $page->html = "

This page is Encrypted

"; + } $parts[] = $this->pageToPlainText($page, false, true); } @@ -290,6 +296,10 @@ public function bookToPlainText(Book $book): string if ($bookChild->isA('chapter')) { $parts[] = $this->chapterToPlainText($bookChild); } else { + if($bookChild->is_encrypted) + { + $bookChild->html = "

This page is Encrypted

"; + } $parts[] = $this->pageToPlainText($bookChild, true, true); } } @@ -317,6 +327,10 @@ public function chapterToMarkdown(Chapter $chapter): string $text = '# ' . $chapter->name . "\n\n"; $text .= $chapter->description . "\n\n"; foreach ($chapter->pages as $page) { + if($page->is_encrypted) + { + $page->html = "

This page is Encrypted

"; + } $text .= $this->pageToMarkdown($page) . "\n\n"; } @@ -334,6 +348,10 @@ public function bookToMarkdown(Book $book): string if ($bookChild instanceof Chapter) { $text .= $this->chapterToMarkdown($bookChild) . "\n\n"; } else { + if($bookChild->is_encrypted) + { + $bookChild->html = "

This page is Encrypted

"; + } $text .= $this->pageToMarkdown($bookChild) . "\n\n"; } } diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php index 8d8da61ec18..c72cc7ce40b 100644 --- a/app/Uploads/ImageService.php +++ b/app/Uploads/ImageService.php @@ -98,7 +98,7 @@ public function saveNew(string $imageName, string $imageData, string $type, int 'type' => $type, 'uploaded_to' => $uploadedTo, ]; - + dump($this->storage->getPublicUrl($fullPath)); if (user()->id !== 0) { $userId = user()->id; $imageDetails['created_by'] = $userId; diff --git a/database/.gitignore b/database/.gitignore old mode 100644 new mode 100755 diff --git a/database/migrations/2024_12_03_062042_add_encrypt_column_in_entity_permissions.php b/database/migrations/2024_12_03_062042_add_encrypt_column_in_entity_permissions.php new file mode 100755 index 00000000000..7ecaae1f617 --- /dev/null +++ b/database/migrations/2024_12_03_062042_add_encrypt_column_in_entity_permissions.php @@ -0,0 +1,28 @@ +boolean('encrypt'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('entity_permissions', function (Blueprint $table) { + $table->removeColumn('encrypt'); + }); + } +}; diff --git a/lang/en/activities.php b/lang/en/activities.php index 092398ef0e1..7813e6b159a 100644 --- a/lang/en/activities.php +++ b/lang/en/activities.php @@ -16,6 +16,10 @@ 'page_restore_notification' => 'Page successfully restored', 'page_move' => 'moved page', 'page_move_notification' => 'Page successfully moved', + 'page_encrypted' => 'page encrypted', + 'page_encrypted_notification' => 'Page successfully encrypted', + 'page_decrypted' => 'page decrypted', + 'page_decrypted_notification' => 'Page successfully decrypted', // Chapters 'chapter_create' => 'created chapter', diff --git a/resources/js/components/collapsible.js b/resources/js/components/collapsible.js index 6f740ed7163..8bd07276019 100644 --- a/resources/js/components/collapsible.js +++ b/resources/js/components/collapsible.js @@ -13,7 +13,7 @@ export class Collapsible extends Component { this.content = this.$refs.content; if (this.trigger) { - this.trigger.addEventListener('click', this.toggle.bind(this)); + this.trigger.addEventListener('click',this.toggle.bind(this)); this.openIfContainsError(); } } diff --git a/resources/js/components/encrypt-decrypt-manager.js b/resources/js/components/encrypt-decrypt-manager.js index 25eb708ecf8..acecb3ae3fc 100644 --- a/resources/js/components/encrypt-decrypt-manager.js +++ b/resources/js/components/encrypt-decrypt-manager.js @@ -1,3 +1,4 @@ +import { update } from 'idb-keyval'; import {Component} from './component'; export class EncryptDecryptManager extends Component @@ -10,6 +11,7 @@ export class EncryptDecryptManager extends Component this.decryptPassword = this.$refs.decryptPasswordInput; this.editBtn = this.$refs.editBtn; this.invalidMsg = this.$refs.invalidPassword; + this.exportMenu = this.$refs.exportMenu; this.url = this.$opts.url; this.pageName = this.$opts.pageName; @@ -17,10 +19,9 @@ export class EncryptDecryptManager extends Component this.encryptDialog = document.querySelector('.encrypt-decrypt-dialog'); this.contentPart = document.querySelector('.page-content'); - this.pageContentPTags = document.querySelector('.page-content').querySelectorAll('p'); - this.pageContent = document.querySelector('.page-content').querySelector('div[dir="auto"]'); this.pageDetailContent = document.querySelector('.page-content').querySelector('.page-detail-content'); - this.encryptIcon = document.querySelector('.page-content').querySelector('.encrypt-icon') + this.encryptInfo = document.querySelector('.page-content').querySelector('.encrypt-message'); + this.invalidPassword = this.encryptDialog.querySelector('.invalid-password'); this.passwordInput = this.encryptDialog.querySelector('#page-encrypt-password'); @@ -65,6 +66,10 @@ export class EncryptDecryptManager extends Component this.passwordInput.addEventListener("input",()=>{ this.invalidPassword.classList.add("hidden"); }) + + this.exportMenu.querySelectorAll('a').forEach(anchor => { + anchor.addEventListener("click", event => this.decryptForExport(event,anchor)); + }); } } @@ -92,7 +97,7 @@ export class EncryptDecryptManager extends Component } } - decryptContent(decryptPassword,updateDecryption = false,forEdit = false) + decryptContent(decryptPassword,updateDecryption = false) { if(decryptPassword.length > 6) { @@ -101,58 +106,37 @@ export class EncryptDecryptManager extends Component content: this.pageDetailContent.innerHTML, decrypt_password: decryptPassword, } - if(!this.is_decrypt) - { - window.$http.post(`${this.url}/decrypt`, decryptData).then(async resp=>{ - if(resp.data.success) - { - // let contents = this.changePageContent(resp.data.contents); - this.decryptPassword.value = ""; - this.pageDetailContent.innerHTML = resp.data.content; - - if(updateDecryption) - { - const data = { - 'html' : resp.data.content, - 'is_encrypted' : forEdit, - 'is_decrypt' : forEdit, - 'decrypt_password' : decryptPassword, - }; - this.updateData(data,false,forEdit); - } - else - { - this.is_decrypt = true; - this.encryptIcon.classList.add("hidden"); - this.pageDetailContent.classList.remove("hidden"); - } + window.$http.post(`${this.url}/decrypt`, decryptData).then(async resp => { + if (resp.data.success) { + + this.decryptPassword.value = ""; + this.pageDetailContent.innerHTML = resp.data.content; + + if (updateDecryption) { + const data = { + 'html': resp.data.content, + 'is_encrypted': false, + 'decrypt_password': decryptPassword, + }; + this.updateData(data, false, false); } - else - { - if(forEdit || updateDecryption) - { - this.invalidPassword.innerHTML = resp.data.message; - this.invalidPassword.classList.remove("hidden"); - this.openDialog(); - } - else - { - this.invalidMsg.innerHTML = resp.data.message; - this.invalidMsg.classList.remove("hidden"); - } + else { + this.is_decrypt = true; + this.encryptInfo.classList.add("hidden"); } - }); - } - else - { - const data = { - 'html' : this.pageDetailContent.innerHTML, - 'is_encrypted' : forEdit, - 'is_decrypt' : forEdit, - 'decrypt_password' : decryptPassword, - }; - this.updateData(data,false,forEdit); - } + } + else { + if (updateDecryption) { + this.invalidPassword.innerHTML = resp.data.message; + this.invalidPassword.classList.remove("hidden"); + this.openDialog(); + } + else { + this.invalidMsg.innerHTML = resp.data.message; + this.invalidMsg.classList.remove("hidden"); + } + } + }); } } @@ -171,30 +155,19 @@ export class EncryptDecryptManager extends Component const response = await this.openDialog(); if(response) { - this.decryptContent(this.encryptDialog.querySelector('#page-encrypt-password').value,true,true); - } - } + const password = this.encryptDialog.querySelector('#page-encrypt-password').value; - getPageContent() - { - const contents = []; + const data = { + 'is_decrypt' : 'FOR_EDIT', + 'decrypt_password' : password, + }; - this.pageContentPTags.forEach(element => { - contents.push(element.innerHTML); - }); - return contents; + this.updateData(data,false,true,this.editBtn.getAttribute('href')) + } } - changePageContent(contents) - { - this.pageContentPTags.forEach((element,index) => { - element.innerHTML = contents[index]; - contents[index] = element.outerHTML; - }); - return contents; - } - async updateData(data,updateEncryption,forEdit) + async updateData(data,updateEncryption,tmpDecrypt = false,link = this.url) { try{ if(updateEncryption) @@ -211,9 +184,9 @@ export class EncryptDecryptManager extends Component window.$http.put(`${this.url}/update-decryption`,data).then(resp=> { if(resp.data.success){ - if(forEdit) + if(tmpDecrypt) { - window.location.href = this.editBtn.getAttribute('href'); + window.location.href = link; } else { @@ -234,4 +207,34 @@ export class EncryptDecryptManager extends Component console.log(error); } } + + async decryptForExport(event,element) + { + event.preventDefault(); + const link = element.getAttribute('href'); + const response = await this.openDialog(); + if(response) + { + const password = this.encryptDialog.querySelector('#page-encrypt-password').value; + + window.$http.post(`${this.url}/validate-password`,{'decrypt_password' : password}).then(async resp=>{ + + if(resp.data.success) + { + const data = { + 'is_decrypt' : 'FOR_EXPORT', + 'decrypt_password' : password, + }; + + this.updateData(data,false,true,link); + } + else + { + this.invalidPassword.innerHTML = 'Invalid Password'; + this.invalidPassword.classList.remove("hidden"); + this.decryptForExport(event); + } + }); + } + } } \ No newline at end of file diff --git a/resources/views/entities/export-menu.blade.php b/resources/views/entities/export-menu.blade.php index a55ab56d199..1ef23aae263 100644 --- a/resources/views/entities/export-menu.blade.php +++ b/resources/views/entities/export-menu.blade.php @@ -1,6 +1,7 @@
diff --git a/resources/views/pages/parts/page-display.blade.php b/resources/views/pages/parts/page-display.blade.php index 91f6deb697f..d6549969016 100644 --- a/resources/views/pages/parts/page-display.blade.php +++ b/resources/views/pages/parts/page-display.blade.php @@ -3,10 +3,11 @@

{{$page->name}}

- @if($page->is_encrypted) -

@icon('lock')

+ + @if($page->is_encrypted && !isset($export)) +
This File is Encrypted To Decrypt Enter Password By Click on View at Right Side Menu
@endif - @endif @@ -220,18 +226,10 @@ class="page-content clearfix"> @include('entities.favourite-action', ['entity' => $page]) @endif @if(userCan('content-export')) - @include('entities.export-menu', ['entity' => $page]) + @include('entities.export-menu', ['entity' => $page,'refs'=> $page->is_encrypted ? 'encrypt-decrypt-manager@export-menu' : '' ]) @endif
-@stop - -@component('common.confirm-dialog', ['title' => trans($page->is_encrypted ? 'common.decrypt' : 'common.encrypt'), 'class' => 'encrypt-decrypt-dialog']) -

- -
- -

-@endcomponent \ No newline at end of file +@stop \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 781b52ad990..b782d5dfa66 100644 --- a/routes/web.php +++ b/routes/web.php @@ -118,6 +118,8 @@ Route::post('/books/{bookSlug}/page/{pageSlug}/decrypt', [EntityControllers\PageController::class, 'decrypt']); Route::put('/books/{bookSlug}/page/{pageSlug}/update-encryption', [EntityControllers\PageController::class, 'updateEncryption']); Route::put('/books/{bookSlug}/page/{pageSlug}/update-decryption', [EntityControllers\PageController::class, 'updateDecryption']); + Route::post('/books/{bookSlug}/page/{pageSlug}/validate-password', [EntityControllers\PageController::class, 'validateDecryptPassword']); + Route::get('/decrypt-password', [EntityControllers\PageController::class, 'validateDecryptPassword']); // Chapters diff --git a/tests/Api/ContentPermissionsApiTest.php b/tests/Api/ContentPermissionsApiTest.php index a62abacc75e..aa07b3cd7ef 100644 --- a/tests/Api/ContentPermissionsApiTest.php +++ b/tests/Api/ContentPermissionsApiTest.php @@ -58,6 +58,7 @@ public function test_read_endpoint_shows_expected_detail() 'create' => false, 'update' => false, 'delete' => true, + 'encrypt' => 0, 'role' => [ 'id' => $role->id, 'display_name' => $role->display_name, @@ -148,6 +149,7 @@ public function test_update_can_set_role_permissions() 'create' => false, 'update' => false, 'delete' => false, + 'encrypt' => 0, 'role' => [ 'id' => $newRoleA->id, 'display_name' => $newRoleA->display_name, @@ -159,6 +161,7 @@ public function test_update_can_set_role_permissions() 'create' => false, 'update' => true, 'delete' => true, + 'encrypt' => 0, 'role' => [ 'id' => $newRoleB->id, 'display_name' => $newRoleB->display_name, diff --git a/tests/Entity/PageTest.php b/tests/Entity/PageTest.php index b96d455eb25..6a548bf7778 100644 --- a/tests/Entity/PageTest.php +++ b/tests/Entity/PageTest.php @@ -356,4 +356,98 @@ public function test_recently_updated_pages_on_home() $resp = $this->get('/'); $this->withHtml($resp)->assertElementContains('#recently-updated-pages', $page->name); } + + public function test_page_encryption() + { + $page = $this->entities->page(); + $this->asEditor(); + $url = $page->getUrl(); + + // Encrypt The page Content + $resp = $this->post("$url/encrypt",['content'=> $page->html]); + $resp->assertStatus(200); + $resp->assertJson([ + 'message' => 'Encrypted SuccessFully', + 'success' => true, + ]); + + $encryptedHtml = $resp->json('content'); + + $data = [ + 'html' => $encryptedHtml, + 'decrypt_password' => 'BlaBLa@123', + 'is_encrypted' => true, + ]; + + // Update Encrypt Data + $pageUpdateResp = $this->put("$url/update-encryption",$data); + $pageUpdateResp->assertStatus(200); + + $pageUpdateResp->assertJson([ + 'message' => 'Encryption Update SuccessFully', + 'success' => true, + ]); + + $page->refresh(); + $this->assertEquals($page->is_encrypted,1); + $this->assertEquals($page->html,$encryptedHtml); + + } + + public function test_page_decryption() + { + $page = $this->entities->page(); + $this->asEditor(); + $url = $page->getUrl(); + + $oldHtml = $page->html; + + // Encrypt The Page Content + $resp = $this->post("$url/encrypt",['content'=> $page->html]); + $resp->assertStatus(200); + $resp->assertJson([ + 'message' => 'Encrypted SuccessFully', + 'success' => true, + ]); + + $encryptedHtml = $resp->json('content'); + $decryptPassword = 'BlaBLa@123'; + + // Update Encrypt Data + $data = [ + 'html' => $encryptedHtml, + 'decrypt_password' => $decryptPassword, + 'is_encrypted' => true, + ]; + + $pageUpdateResp = $this->put("$url/update-encryption",$data); + $pageUpdateResp->assertStatus(200); + $page->refresh(); + + // Decrypt The Page Content + $decryptData = [ + 'decrypt_password' => $decryptPassword, + 'content' => $page->html, + ]; + + $pageDecryptResp = $this->post("$url/decrypt",$decryptData); + $pageDecryptResp->assertStatus(200); + + $pageDecryptResp->assertJson(['message' => 'Decrypted SuccessFully','success' => true]); + $this->assertEquals($oldHtml,$pageDecryptResp->json('content')); + + // Update Decrypt Data + $decryptData = [ + 'html'=> $pageDecryptResp->json('content'), + 'is_encrypted'=> false, + 'decrypt_password'=> $decryptPassword, + ]; + + $pageDecryptUpdateResponse = $this->put("$url/update-decryption",$decryptData); + $pageDecryptUpdateResponse->assertStatus(200); + + $page->refresh(); + + $this->assertEquals($page->is_encrypted,0); + } } From a9ccf522d31107f227d1afc8e7e765687be1e33d Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Wed, 4 Dec 2024 18:18:12 +0530 Subject: [PATCH 04/10] "Fix Lint JS and PHP" --- app/App/HomeController.php | 6 +- app/Entities/Controllers/PageController.php | 54 ++--- .../Controllers/PageExportController.php | 15 +- app/Entities/Repos/BaseRepo.php | 3 +- app/Entities/Repos/PageRepo.php | 36 +-- app/Entities/Tools/BookContents.php | 2 +- app/Entities/Tools/ExportFormatter.php | 12 +- app/Search/SearchRunner.php | 6 +- .../2024_11_25_123200_add_new_permissions.php | 5 +- ...80138_add_is_encrypted_column_in_pages.php | 1 - resources/js/components/collapsible.js | 2 +- .../js/components/encrypt-decrypt-manager.js | 216 +++++++----------- routes/web.php | 2 +- tests/Api/ContentPermissionsApiTest.php | 2 +- tests/Entity/PageTest.php | 27 ++- 15 files changed, 154 insertions(+), 235 deletions(-) diff --git a/app/App/HomeController.php b/app/App/HomeController.php index 3beaa4e9964..7aa22574031 100644 --- a/app/App/HomeController.php +++ b/app/App/HomeController.php @@ -43,8 +43,8 @@ public function index( $recents = $this->isSignedIn() ? $recentlyViewed->run(12 * $recentFactor, 1) : $this->queries->books->visibleForList()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get(); - $recents = $recents->filter(function($recent){ - if($recent instanceof Page) { + $recents = $recents->filter(function ($recent) { + if ($recent instanceof Page) { return !$recent->is_encrypted; } return true; @@ -52,7 +52,7 @@ public function index( $favourites = $topFavourites->run(6); $recentlyUpdatedPages = $this->queries->pages->visibleForList() ->where('draft', false) - ->where('is_encrypted',false) + ->where('is_encrypted', false) ->orderBy('updated_at', 'desc') ->take($favourites->count() > 0 ? 5 : 10) ->get(); diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index be1f2f40e2e..b61edf9d1a2 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -199,8 +199,7 @@ public function edit(Request $request, string $bookSlug, string $pageSlug) $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); - if(session()->get('is_decrypt') == 'FOR_EDIT') - { + if (session()->get('is_decrypt') == 'FOR_EDIT') { $page->html = decrypt($page->html); session()->remove('is_decrypt'); } @@ -229,10 +228,9 @@ public function update(Request $request, string $bookSlug, string $pageSlug) $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); - if($page->is_decrypt == 'FOR_EDIT') - { + if (session()->get('is_decrypt') == 'FOR_EDIT') { $request['html'] = encrypt($request['html']); - $request['is_decrypt'] = 'NONE'; + session()->put('is_decrypt', 'NONE'); } $this->pageRepo->update($page, $request->all()); @@ -481,56 +479,50 @@ public function copy(Request $request, Cloner $cloner, string $bookSlug, string return redirect($pageCopy->getUrl()); } - public function encrypt(Request $request,string $bookSlug, string $pageSlug) + public function encrypt(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); - return $this->pageRepo->encryptPageContent($request->all(),$page); + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + return $this->pageRepo->encryptPageContent($request->all(), $page); } - public function decrypt(Request $request,string $bookSlug, string $pageSlug) + public function decrypt(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); - return $this->pageRepo->decryptPageContent($request->all(),$page); + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + return $this->pageRepo->decryptPageContent($request->all(), $page); } - public function updateEncryption(Request $request,string $bookSlug, string $pageSlug) + public function updateEncryption(Request $request, string $bookSlug, string $pageSlug) { - $this->validate($request,[ + $this->validate($request, [ 'html' => ['required'], 'decrypt_password' => ['required'], 'is_encrypted' => ['required','boolean'], ]); - $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->pageRepo->update($page, $request->all()); return response()->json(['message' => 'Encryption Update SuccessFully','success' => true]); - } - public function updateDecryption(Request $request,string $bookSlug, string $pageSlug) + public function updateDecryption(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); - if($this->validateDecryptPassword($request, $bookSlug, $pageSlug)) - { - if($request->has('is_decrypt')) - { - session()->put('is_decrypt',$request->get('is_decrypt')); - \Log::info('Update : ' .session()->get('is_decrypt')); + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + if ($this->validateDecryptPassword($request, $bookSlug, $pageSlug)) { + if ($request->has('is_decrypt')) { + session()->put('is_decrypt', $request->get('is_decrypt')); } $this->pageRepo->update($page, $request->all()); return response()->json(['contents' => [],'message' => 'Decrypted SuccessFully','success' => true]); - } - else - { + } else { return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); } } - public function validateDecryptPassword(Request $request,string $bookSlug, string $pageSlug) + public function validateDecryptPassword(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->queries->findVisibleBySlugsOrFail($bookSlug,$pageSlug); - return Hash::check($request->get('decrypt_password'),$page->decrypt_password) ? - response()->json(['success'=>true]) : - response()->json(['success'=>false]); + $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); + return Hash::check($request->get('decrypt_password'), $page->decrypt_password) ? + response()->json(['success' => true]) : + response()->json(['success' => false]); } } diff --git a/app/Entities/Controllers/PageExportController.php b/app/Entities/Controllers/PageExportController.php index ac5e1472301..2abf27e6d45 100644 --- a/app/Entities/Controllers/PageExportController.php +++ b/app/Entities/Controllers/PageExportController.php @@ -61,7 +61,7 @@ public function plainText(string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->validatePageEncrypted($page); - $pageText = $this->exportFormatter->pageToPlainText($page,$page->is_encrypted); + $pageText = $this->exportFormatter->pageToPlainText($page, $page->is_encrypted); return $this->download()->directly($pageText, $pageSlug . '.txt'); } @@ -82,17 +82,12 @@ public function markdown(string $bookSlug, string $pageSlug) public function validatePageEncrypted(Page $page) { - - if($page->is_encrypted) - { - if(session()->get('is_decrypt') == 'FOR_EXPORT') - { + if ($page->is_encrypted) { + if (session()->get('is_decrypt') == 'FOR_EXPORT') { $page->html = decrypt($page->html); - session()->put('is_decrypt','NONE'); + session()->put('is_decrypt', 'NONE'); return true; - } - else - { + } else { return redirect($page->getUrl()); } } diff --git a/app/Entities/Repos/BaseRepo.php b/app/Entities/Repos/BaseRepo.php index f964aa8852f..6aee507dc64 100644 --- a/app/Entities/Repos/BaseRepo.php +++ b/app/Entities/Repos/BaseRepo.php @@ -76,8 +76,7 @@ public function update(Entity $entity, array $input) } $entity->rebuildPermissions(); - if((array_key_exists('is_encrypted',$input) && $input['is_encrypted'] == true) || !(($entity InstanceOf Page) && $entity->is_encrypted == true)) - { + if ((array_key_exists('is_encrypted', $input) && $input['is_encrypted'] == true) || !(($entity instanceof Page) && $entity->is_encrypted == true)) { $entity->indexForSearch(); } $this->referenceStore->updateForEntity($entity); diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 4991a6cd61a..6aea2db031e 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -100,11 +100,10 @@ public function update(Page $page, array $input): Page $oldMarkdown = $page->markdown; //Make Hashable decrypt Password - if(array_key_exists('decrypt_password',$input)) - { + if (array_key_exists('decrypt_password', $input)) { $input['decrypt_password'] = Hash::make($input['decrypt_password']); } - + $this->updateTemplateStatusAndContentFromInput($page, $input); $this->baseRepo->update($page, $input); @@ -124,19 +123,13 @@ public function update(Page $page, array $input): Page $this->revisionRepo->storeNewForPage($page, $summary); } - if(array_key_exists('is_encrypted',$input)) - { - if($input['is_encrypted'] == true) - { + if (array_key_exists('is_encrypted', $input)) { + if ($input['is_encrypted'] == true) { Activity::add(ActivityType::PAGE_ENCRYPTED, $page); - } - else if($input['is_encrypted'] == false) - { + } else if ($input['is_encrypted'] == false) { Activity::add(ActivityType::PAGE_DECRYPTED, $page); } - } - else if(!array_key_exists('is_decrypt',$input)) - { + } else if (!array_key_exists('is_decrypt', $input)) { Activity::add(ActivityType::PAGE_UPDATE, $page); } @@ -304,28 +297,21 @@ protected function getNewPriority(Page $page): int public function encryptPageContent(array $data, Page $page) { - if(!$page->is_encrypted) - { + if (!$page->is_encrypted) { $content = encrypt($data['content']); return response()->json(['content' => $content,'message' => 'Encrypted SuccessFully','success' => true]); - } - else - { + } else { return response()->json(['content' => '','message' => 'Already Encrypted','success' => false]); } } public function decryptPageContent(array $data, Page $page) { - if($page->is_encrypted) - { - if(Hash::check($data['decrypt_password'],$page->decrypt_password)) - { + if ($page->is_encrypted) { + if (Hash::check($data['decrypt_password'], $page->decrypt_password)) { $content = decrypt($data['content']); return response()->json(['content' => $content,'message' => 'Decrypted SuccessFully','success' => true]); - } - else - { + } else { return response()->json(['contents' => [],'message' => 'Decrypt Password is Wrong','success' => false]); } } diff --git a/app/Entities/Tools/BookContents.php b/app/Entities/Tools/BookContents.php index 5223408ef59..94a5373a12a 100644 --- a/app/Entities/Tools/BookContents.php +++ b/app/Entities/Tools/BookContents.php @@ -44,7 +44,7 @@ public function getTree(bool $showDrafts = false, bool $renderPages = false): Co $pages = $this->getPages($showDrafts, $renderPages); // Check For Encrypted Pages - $pages->each(function($page){ + $pages->each(function ($page) { $page->html = $page->is_encrypted ? '

This page is encrypted

' : $page->html; }); diff --git a/app/Entities/Tools/ExportFormatter.php b/app/Entities/Tools/ExportFormatter.php index 26fe1531cd4..b1d9a1b86cf 100644 --- a/app/Entities/Tools/ExportFormatter.php +++ b/app/Entities/Tools/ExportFormatter.php @@ -272,8 +272,7 @@ public function chapterToPlainText(Chapter $chapter): string $parts = []; foreach ($chapter->getVisiblePages() as $page) { - if($page->is_encrypted) - { + if ($page->is_encrypted) { $page->html = "

This page is Encrypted

"; } $parts[] = $this->pageToPlainText($page, false, true); @@ -296,8 +295,7 @@ public function bookToPlainText(Book $book): string if ($bookChild->isA('chapter')) { $parts[] = $this->chapterToPlainText($bookChild); } else { - if($bookChild->is_encrypted) - { + if ($bookChild->is_encrypted) { $bookChild->html = "

This page is Encrypted

"; } $parts[] = $this->pageToPlainText($bookChild, true, true); @@ -327,8 +325,7 @@ public function chapterToMarkdown(Chapter $chapter): string $text = '# ' . $chapter->name . "\n\n"; $text .= $chapter->description . "\n\n"; foreach ($chapter->pages as $page) { - if($page->is_encrypted) - { + if ($page->is_encrypted) { $page->html = "

This page is Encrypted

"; } $text .= $this->pageToMarkdown($page) . "\n\n"; @@ -348,8 +345,7 @@ public function bookToMarkdown(Book $book): string if ($bookChild instanceof Chapter) { $text .= $this->chapterToMarkdown($bookChild) . "\n\n"; } else { - if($bookChild->is_encrypted) - { + if ($bookChild->is_encrypted) { $bookChild->html = "

This page is Encrypted

"; } $text .= $this->pageToMarkdown($bookChild) . "\n\n"; diff --git a/app/Search/SearchRunner.php b/app/Search/SearchRunner.php index 9da4aa3b0cd..116324c41d8 100644 --- a/app/Search/SearchRunner.php +++ b/app/Search/SearchRunner.php @@ -159,9 +159,9 @@ protected function buildQuery(SearchOptions $searchOpts, string $entityType): El $inputTerm = str_replace('\\', '\\\\', $exact->value); $query->where('name', 'like', '%' . $inputTerm . '%') ->orWhere($entityModelInstance->textField, 'like', '%' . $inputTerm . '%'); - if ($entityModelInstance instanceof Page) { - $query->Where('is_encrypted','!=',1); - } + if ($entityModelInstance instanceof Page) { + $query->Where('is_encrypted', '!=', 1); + } }; $exact->negated ? $entityQuery->whereNot($filter) : $entityQuery->where($filter); diff --git a/database/migrations/2024_11_25_123200_add_new_permissions.php b/database/migrations/2024_11_25_123200_add_new_permissions.php index 7c1b50ffa66..1cb5a6a5adb 100644 --- a/database/migrations/2024_11_25_123200_add_new_permissions.php +++ b/database/migrations/2024_11_25_123200_add_new_permissions.php @@ -15,13 +15,13 @@ public function up(): void { // get Admin Role Id $adminRoleId = DB::table('roles')->where('display_name', '=', 'admin')->first()->id; - + // Create & attach new entity permissions $entities = ['Book', 'Page', 'Chapter', 'bookshelf']; $ops = ['Restrict All', 'Restrict Own','Encrypt All','Encrypt Own']; foreach ($entities as $entity) { foreach ($ops as $op) { - if(($op === 'Encrypt All' || $op === 'Encrypt Own') && $entity !== 'Page'){ + if (($op === 'Encrypt All' || $op === 'Encrypt Own') && $entity !== 'Page') { break; } $permissionId = DB::table('role_permissions')->insertGetId([ @@ -36,7 +36,6 @@ public function up(): void ]); } } - } /** diff --git a/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php b/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php index cea2f229513..504f9419156 100755 --- a/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php +++ b/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php @@ -12,7 +12,6 @@ public function up(): void { Schema::table('pages', function (Blueprint $table) { - $table->boolean('is_encrypted')->after('priority')->default(false); $table->boolean('is_decrypt')->after('is_encrypted'); $table->text('decrypt_password')->after('is_encrypted'); diff --git a/resources/js/components/collapsible.js b/resources/js/components/collapsible.js index 8bd07276019..6f740ed7163 100644 --- a/resources/js/components/collapsible.js +++ b/resources/js/components/collapsible.js @@ -13,7 +13,7 @@ export class Collapsible extends Component { this.content = this.$refs.content; if (this.trigger) { - this.trigger.addEventListener('click',this.toggle.bind(this)); + this.trigger.addEventListener('click', this.toggle.bind(this)); this.openIfContainsError(); } } diff --git a/resources/js/components/encrypt-decrypt-manager.js b/resources/js/components/encrypt-decrypt-manager.js index acecb3ae3fc..200ee77db54 100644 --- a/resources/js/components/encrypt-decrypt-manager.js +++ b/resources/js/components/encrypt-decrypt-manager.js @@ -1,10 +1,8 @@ -import { update } from 'idb-keyval'; import {Component} from './component'; -export class EncryptDecryptManager extends Component -{ - setup() - { +export class EncryptDecryptManager extends Component { + + setup() { this.container = this.$el; this.encryptBtn = this.$refs.encryptBtn; this.decryptSubmitBtn = this.$refs.decryptSubmitBtn; @@ -22,7 +20,6 @@ export class EncryptDecryptManager extends Component this.pageDetailContent = document.querySelector('.page-content').querySelector('.page-detail-content'); this.encryptInfo = document.querySelector('.page-content').querySelector('.encrypt-message'); - this.invalidPassword = this.encryptDialog.querySelector('.invalid-password'); this.passwordInput = this.encryptDialog.querySelector('#page-encrypt-password'); @@ -31,210 +28,167 @@ export class EncryptDecryptManager extends Component this.setupListener(); } - setupListener() - { - this.encryptBtn.addEventListener("click",async event => { + setupListener() { + this.encryptBtn.addEventListener('click', async event => { event.preventDefault(); const response = await this.openDialog(); - if(response) - { - if(this.pageIsEncrypted == 1) - { - this.decryptContent(this.passwordInput.value,true,false); - } - else - { + if (response) { + if (this.pageIsEncrypted === 1) { + this.decryptContent(this.passwordInput.value, true, false); + } else { this.encryptContent(); } } }); - - if(this.pageIsEncrypted == 1) - { - this.contentPart.addEventListener("mousedown", event => event.preventDefault()); - this.contentPart.addEventListener("selectstart", event => event.preventDefault()); - this.contentPart.addEventListener("copy", event => event.preventDefault()); - this.decryptPassword.addEventListener("input",()=>{this.invalidMsg.classList.add('hidden')}); - this.decryptSubmitBtn.addEventListener("click",()=>this.decryptContent(this.decryptPassword.value)); - this.editBtn.addEventListener("click",event=>this.decryptContentOnEdit(event)); - this.decryptPassword.addEventListener("keydown",event => { - if(event.key == "Enter") - { + + if (this.pageIsEncrypted === 1) { + this.contentPart.addEventListener('mousedown', event => event.preventDefault()); + this.contentPart.addEventListener('selectstart', event => event.preventDefault()); + this.contentPart.addEventListener('copy', event => event.preventDefault()); + this.decryptPassword.addEventListener('input', () => { this.invalidMsg.classList.add('hidden'); }); + this.decryptSubmitBtn.addEventListener('click', () => this.decryptContent(this.decryptPassword.value)); + this.editBtn.addEventListener('click', event => this.decryptContentOnEdit(event)); + this.decryptPassword.addEventListener('keydown', event => { + if (event.key === 'Enter') { this.decryptContent(this.decryptPassword.value); } }); - this.passwordInput.addEventListener("input",()=>{ - this.invalidPassword.classList.add("hidden"); - }) + this.passwordInput.addEventListener('input', () => { + this.invalidPassword.classList.add('hidden'); + }); this.exportMenu.querySelectorAll('a').forEach(anchor => { - anchor.addEventListener("click", event => this.decryptForExport(event,anchor)); + anchor.addEventListener('click', event => this.decryptForExport(event, anchor)); }); } } - encryptContent() - { + encryptContent() { const password = this.passwordInput.value; - if(password.length > 6) - { + if (password.length > 6) { const contents = this.pageDetailContent.innerHTML; - window.$http.post(`${this.url}/encrypt`, {content: contents}).then(resp=>{ - if(resp.data.success) - { - // let contents = this.changePageContent(resp.data.contents); - this.pageDetailContent.innerHTML = resp.data.content; - - const data = { - 'html' : resp.data.content, - 'is_encrypted' : true, - 'decrypt_password' : password, + window.$http.post(`${this.url}/encrypt`, {content: contents}).then(resp => { + if (resp.data.success) { + // let contents = this.changePageContent(resp.data.contents); + this.pageDetailContent.innerHTML = resp.data.content; + + const data = { + html: resp.data.content, + is_encrypted: true, + decrypt_password: password, + }; + this.updateData(data, true, false); } - this.updateData(data,true,false); - } }); } } - decryptContent(decryptPassword,updateDecryption = false) - { - if(decryptPassword.length > 6) - { - + decryptContent(decryptPassword, updateDecryption = false) { + if (decryptPassword.length > 6) { const decryptData = { content: this.pageDetailContent.innerHTML, decrypt_password: decryptPassword, - } + }; window.$http.post(`${this.url}/decrypt`, decryptData).then(async resp => { if (resp.data.success) { - - this.decryptPassword.value = ""; + this.decryptPassword.value = ''; this.pageDetailContent.innerHTML = resp.data.content; if (updateDecryption) { const data = { - 'html': resp.data.content, - 'is_encrypted': false, - 'decrypt_password': decryptPassword, + html: resp.data.content, + is_encrypted: false, + decrypt_password: decryptPassword, }; this.updateData(data, false, false); - } - else { + } else { this.is_decrypt = true; - this.encryptInfo.classList.add("hidden"); - } - } - else { - if (updateDecryption) { - this.invalidPassword.innerHTML = resp.data.message; - this.invalidPassword.classList.remove("hidden"); - this.openDialog(); - } - else { - this.invalidMsg.innerHTML = resp.data.message; - this.invalidMsg.classList.remove("hidden"); + this.encryptInfo.classList.add('hidden'); } + } else if (updateDecryption) { + this.invalidPassword.innerHTML = resp.data.message; + this.invalidPassword.classList.remove('hidden'); + this.openDialog(); + } else { + this.invalidMsg.innerHTML = resp.data.message; + this.invalidMsg.classList.remove('hidden'); } }); - } } - async openDialog() - { + async openDialog() { this.encryptDialog.querySelector('#page-encrypt-password').value = ''; const dialog = window.$components.firstOnElement(this.encryptDialog, 'confirm-dialog'); const response = await dialog.show(); return response; } - async decryptContentOnEdit(event) - { + async decryptContentOnEdit(event) { event.preventDefault(); const response = await this.openDialog(); - if(response) - { + if (response) { const password = this.encryptDialog.querySelector('#page-encrypt-password').value; const data = { - 'is_decrypt' : 'FOR_EDIT', - 'decrypt_password' : password, + is_decrypt: 'FOR_EDIT', + decrypt_password: password, }; - this.updateData(data,false,true,this.editBtn.getAttribute('href')) + this.updateData(data, false, true, this.editBtn.getAttribute('href')); } } - - async updateData(data,updateEncryption,tmpDecrypt = false,link = this.url) - { - try{ - if(updateEncryption) - { - window.$http.put(`${this.url}/update-encryption`,data).then(resp=> - { - if(resp.data.success){ - window.location.reload(); + async updateData(data, updateEncryption, tmpDecrypt = false, link = this.url) { + try { + if (updateEncryption) { + window.$http.put(`${this.url}/update-encryption`, data).then(resp => { + if (resp.data.success) { + window.location.reload(); } }); - } - else - { - window.$http.put(`${this.url}/update-decryption`,data).then(resp=> - { - if(resp.data.success){ - if(tmpDecrypt) - { + } else { + window.$http.put(`${this.url}/update-decryption`, data).then(resp => { + if (resp.data.success) { + if (tmpDecrypt) { window.location.href = link; - } - else - { + } else { window.location.reload(); } - } - else - { + } else { this.invalidMsg.value = resp.data.message; this.invalidMsg.classList.remove('hidden'); } }); } - - } - catch(error) - { - console.log(error); + } catch (error) { + console.error(error); } } - - async decryptForExport(event,element) - { + + async decryptForExport(event, element) { event.preventDefault(); const link = element.getAttribute('href'); const response = await this.openDialog(); - if(response) - { + if (response) { const password = this.encryptDialog.querySelector('#page-encrypt-password').value; - window.$http.post(`${this.url}/validate-password`,{'decrypt_password' : password}).then(async resp=>{ - - if(resp.data.success) - { + window.$http.post(`${this.url}/validate-password`, {decrypt_password: password}).then(async resp => { + if (resp.data.success) { const data = { - 'is_decrypt' : 'FOR_EXPORT', - 'decrypt_password' : password, + is_decrypt: 'FOR_EXPORT', + decrypt_password: password, }; - - this.updateData(data,false,true,link); - } - else - { + + this.updateData(data, false, true, link); + } else { this.invalidPassword.innerHTML = 'Invalid Password'; - this.invalidPassword.classList.remove("hidden"); + this.invalidPassword.classList.remove('hidden'); this.decryptForExport(event); } }); } } -} \ No newline at end of file + +} diff --git a/routes/web.php b/routes/web.php index b782d5dfa66..2cec0b4ba7c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -120,7 +120,7 @@ Route::put('/books/{bookSlug}/page/{pageSlug}/update-decryption', [EntityControllers\PageController::class, 'updateDecryption']); Route::post('/books/{bookSlug}/page/{pageSlug}/validate-password', [EntityControllers\PageController::class, 'validateDecryptPassword']); Route::get('/decrypt-password', [EntityControllers\PageController::class, 'validateDecryptPassword']); - + // Chapters Route::get('/books/{bookSlug}/chapter/{chapterSlug}/create-page', [EntityControllers\PageController::class, 'create']); diff --git a/tests/Api/ContentPermissionsApiTest.php b/tests/Api/ContentPermissionsApiTest.php index aa07b3cd7ef..b64e011d945 100644 --- a/tests/Api/ContentPermissionsApiTest.php +++ b/tests/Api/ContentPermissionsApiTest.php @@ -161,7 +161,7 @@ public function test_update_can_set_role_permissions() 'create' => false, 'update' => true, 'delete' => true, - 'encrypt' => 0, + 'encrypt' => 0, 'role' => [ 'id' => $newRoleB->id, 'display_name' => $newRoleB->display_name, diff --git a/tests/Entity/PageTest.php b/tests/Entity/PageTest.php index 6a548bf7778..fad002be7da 100644 --- a/tests/Entity/PageTest.php +++ b/tests/Entity/PageTest.php @@ -364,7 +364,7 @@ public function test_page_encryption() $url = $page->getUrl(); // Encrypt The page Content - $resp = $this->post("$url/encrypt",['content'=> $page->html]); + $resp = $this->post("$url/encrypt", ['content' => $page->html]); $resp->assertStatus(200); $resp->assertJson([ 'message' => 'Encrypted SuccessFully', @@ -380,7 +380,7 @@ public function test_page_encryption() ]; // Update Encrypt Data - $pageUpdateResp = $this->put("$url/update-encryption",$data); + $pageUpdateResp = $this->put("$url/update-encryption", $data); $pageUpdateResp->assertStatus(200); $pageUpdateResp->assertJson([ @@ -389,9 +389,8 @@ public function test_page_encryption() ]); $page->refresh(); - $this->assertEquals($page->is_encrypted,1); - $this->assertEquals($page->html,$encryptedHtml); - + $this->assertEquals($page->is_encrypted, 1); + $this->assertEquals($page->html, $encryptedHtml); } public function test_page_decryption() @@ -403,7 +402,7 @@ public function test_page_decryption() $oldHtml = $page->html; // Encrypt The Page Content - $resp = $this->post("$url/encrypt",['content'=> $page->html]); + $resp = $this->post("$url/encrypt", ['content' => $page->html]); $resp->assertStatus(200); $resp->assertJson([ 'message' => 'Encrypted SuccessFully', @@ -420,7 +419,7 @@ public function test_page_decryption() 'is_encrypted' => true, ]; - $pageUpdateResp = $this->put("$url/update-encryption",$data); + $pageUpdateResp = $this->put("$url/update-encryption", $data); $pageUpdateResp->assertStatus(200); $page->refresh(); @@ -430,24 +429,24 @@ public function test_page_decryption() 'content' => $page->html, ]; - $pageDecryptResp = $this->post("$url/decrypt",$decryptData); + $pageDecryptResp = $this->post("$url/decrypt", $decryptData); $pageDecryptResp->assertStatus(200); $pageDecryptResp->assertJson(['message' => 'Decrypted SuccessFully','success' => true]); - $this->assertEquals($oldHtml,$pageDecryptResp->json('content')); + $this->assertEquals($oldHtml, $pageDecryptResp->json('content')); // Update Decrypt Data $decryptData = [ - 'html'=> $pageDecryptResp->json('content'), - 'is_encrypted'=> false, - 'decrypt_password'=> $decryptPassword, + 'html' => $pageDecryptResp->json('content'), + 'is_encrypted' => false, + 'decrypt_password' => $decryptPassword, ]; - $pageDecryptUpdateResponse = $this->put("$url/update-decryption",$decryptData); + $pageDecryptUpdateResponse = $this->put("$url/update-decryption", $decryptData); $pageDecryptUpdateResponse->assertStatus(200); $page->refresh(); - $this->assertEquals($page->is_encrypted,0); + $this->assertEquals($page->is_encrypted, 0); } } From 5947bb9c9d7bc8e48210228b4516185cd3bd6672 Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Wed, 4 Dec 2024 19:25:47 +0530 Subject: [PATCH 05/10] "Rename 'decrypt_password' to 'password' in Page, Page model, and related files; update migrations and tests accordingly." --- app/Entities/Controllers/PageController.php | 5 ++- app/Entities/Models/Page.php | 2 +- app/Entities/Repos/PageRepo.php | 6 ++-- .../2024_11_25_123200_add_new_permissions.php | 30 +++++++---------- ...80138_add_is_encrypted_column_in_pages.php | 1 - ...pt_password_to_password_in_pages_table.php | 28 ++++++++++++++++ .../js/components/encrypt-decrypt-manager.js | 33 +++++++++---------- tests/Entity/PageTest.php | 8 ++--- 8 files changed, 66 insertions(+), 47 deletions(-) create mode 100755 database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index b61edf9d1a2..600187377e9 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -201,7 +201,6 @@ public function edit(Request $request, string $bookSlug, string $pageSlug) if (session()->get('is_decrypt') == 'FOR_EDIT') { $page->html = decrypt($page->html); - session()->remove('is_decrypt'); } $editorData = new PageEditorData($page, $this->entityQueries, $request->query('editor', '')); @@ -495,7 +494,7 @@ public function updateEncryption(Request $request, string $bookSlug, string $pag { $this->validate($request, [ 'html' => ['required'], - 'decrypt_password' => ['required'], + 'password' => ['required'], 'is_encrypted' => ['required','boolean'], ]); @@ -521,7 +520,7 @@ public function updateDecryption(Request $request, string $bookSlug, string $pag public function validateDecryptPassword(Request $request, string $bookSlug, string $pageSlug) { $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); - return Hash::check($request->get('decrypt_password'), $page->decrypt_password) ? + return Hash::check($request->get('password'), $page->password) ? response()->json(['success' => true]) : response()->json(['success' => false]); } diff --git a/app/Entities/Models/Page.php b/app/Entities/Models/Page.php index b8180f133e6..bc4bbad7179 100644 --- a/app/Entities/Models/Page.php +++ b/app/Entities/Models/Page.php @@ -33,7 +33,7 @@ class Page extends BookChild { use HasFactory; - protected $fillable = ['name', 'priority','is_encrypted','decrypt_password','is_decrypt']; + protected $fillable = ['name', 'priority','is_encrypted','password']; public string $textField = 'text'; public string $htmlField = 'html'; diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 6aea2db031e..2050db00a11 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -100,8 +100,8 @@ public function update(Page $page, array $input): Page $oldMarkdown = $page->markdown; //Make Hashable decrypt Password - if (array_key_exists('decrypt_password', $input)) { - $input['decrypt_password'] = Hash::make($input['decrypt_password']); + if (array_key_exists('password', $input)) { + $input['password'] = Hash::make($input['password']); } $this->updateTemplateStatusAndContentFromInput($page, $input); @@ -308,7 +308,7 @@ public function encryptPageContent(array $data, Page $page) public function decryptPageContent(array $data, Page $page) { if ($page->is_encrypted) { - if (Hash::check($data['decrypt_password'], $page->decrypt_password)) { + if (Hash::check($data['password'], $page->password)) { $content = decrypt($data['content']); return response()->json(['content' => $content,'message' => 'Decrypted SuccessFully','success' => true]); } else { diff --git a/database/migrations/2024_11_25_123200_add_new_permissions.php b/database/migrations/2024_11_25_123200_add_new_permissions.php index 1cb5a6a5adb..1d15615b24b 100644 --- a/database/migrations/2024_11_25_123200_add_new_permissions.php +++ b/database/migrations/2024_11_25_123200_add_new_permissions.php @@ -17,24 +17,18 @@ public function up(): void $adminRoleId = DB::table('roles')->where('display_name', '=', 'admin')->first()->id; // Create & attach new entity permissions - $entities = ['Book', 'Page', 'Chapter', 'bookshelf']; - $ops = ['Restrict All', 'Restrict Own','Encrypt All','Encrypt Own']; - foreach ($entities as $entity) { - foreach ($ops as $op) { - if (($op === 'Encrypt All' || $op === 'Encrypt Own') && $entity !== 'Page') { - break; - } - $permissionId = DB::table('role_permissions')->insertGetId([ - 'name' => strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op)), - 'display_name' => $op . ' ' . $entity . 's', - 'created_at' => Carbon::now()->toDateTimeString(), - 'updated_at' => Carbon::now()->toDateTimeString(), - ]); - DB::table('permission_role')->insert([ - 'role_id' => $adminRoleId, - 'permission_id' => $permissionId, - ]); - } + $ops = ['Encrypt All','Encrypt Own']; + foreach ($ops as $op) { + $permissionId = DB::table('role_permissions')->insertGetId([ + 'name' => strtolower('Page') . '-' . strtolower(str_replace(' ', '-', $op)), + 'display_name' => $op . ' ' . 'Page' . 's', + 'created_at' => Carbon::now()->toDateTimeString(), + 'updated_at' => Carbon::now()->toDateTimeString(), + ]); + DB::table('permission_role')->insert([ + 'role_id' => $adminRoleId, + 'permission_id' => $permissionId, + ]); } } diff --git a/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php b/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php index 504f9419156..ce5ba932491 100755 --- a/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php +++ b/database/migrations/2024_11_27_080138_add_is_encrypted_column_in_pages.php @@ -13,7 +13,6 @@ public function up(): void { Schema::table('pages', function (Blueprint $table) { $table->boolean('is_encrypted')->after('priority')->default(false); - $table->boolean('is_decrypt')->after('is_encrypted'); $table->text('decrypt_password')->after('is_encrypted'); }); } diff --git a/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php b/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php new file mode 100755 index 00000000000..8a035d5f2bb --- /dev/null +++ b/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php @@ -0,0 +1,28 @@ +renameColumn('decrypt_password','password'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('pages', function (Blueprint $table) { + // + }); + } +}; diff --git a/resources/js/components/encrypt-decrypt-manager.js b/resources/js/components/encrypt-decrypt-manager.js index 200ee77db54..ec528068941 100644 --- a/resources/js/components/encrypt-decrypt-manager.js +++ b/resources/js/components/encrypt-decrypt-manager.js @@ -33,7 +33,8 @@ export class EncryptDecryptManager extends Component { event.preventDefault(); const response = await this.openDialog(); if (response) { - if (this.pageIsEncrypted === 1) { + // eslint-disable-next-line radix + if (parseInt(this.pageIsEncrypted) === 1) { this.decryptContent(this.passwordInput.value, true, false); } else { this.encryptContent(); @@ -41,7 +42,8 @@ export class EncryptDecryptManager extends Component { } }); - if (this.pageIsEncrypted === 1) { + // eslint-disable-next-line radix + if (parseInt(this.pageIsEncrypted) === 1) { this.contentPart.addEventListener('mousedown', event => event.preventDefault()); this.contentPart.addEventListener('selectstart', event => event.preventDefault()); this.contentPart.addEventListener('copy', event => event.preventDefault()); @@ -64,19 +66,16 @@ export class EncryptDecryptManager extends Component { } encryptContent() { - const password = this.passwordInput.value; - if (password.length > 6) { + const decryptPassword = this.passwordInput.value; + if (decryptPassword.length > 6) { const contents = this.pageDetailContent.innerHTML; window.$http.post(`${this.url}/encrypt`, {content: contents}).then(resp => { if (resp.data.success) { - // let contents = this.changePageContent(resp.data.contents); - this.pageDetailContent.innerHTML = resp.data.content; - const data = { html: resp.data.content, is_encrypted: true, - decrypt_password: password, + password: decryptPassword, }; this.updateData(data, true, false); } @@ -88,21 +87,21 @@ export class EncryptDecryptManager extends Component { if (decryptPassword.length > 6) { const decryptData = { content: this.pageDetailContent.innerHTML, - decrypt_password: decryptPassword, + password: decryptPassword, }; window.$http.post(`${this.url}/decrypt`, decryptData).then(async resp => { if (resp.data.success) { this.decryptPassword.value = ''; - this.pageDetailContent.innerHTML = resp.data.content; if (updateDecryption) { const data = { html: resp.data.content, is_encrypted: false, - decrypt_password: decryptPassword, + password: decryptPassword, }; this.updateData(data, false, false); } else { + this.pageDetailContent.innerHTML = resp.data.content; this.is_decrypt = true; this.encryptInfo.classList.add('hidden'); } @@ -129,11 +128,11 @@ export class EncryptDecryptManager extends Component { event.preventDefault(); const response = await this.openDialog(); if (response) { - const password = this.encryptDialog.querySelector('#page-encrypt-password').value; + const decryptPassword = this.encryptDialog.querySelector('#page-encrypt-password').value; const data = { is_decrypt: 'FOR_EDIT', - decrypt_password: password, + password: decryptPassword, }; this.updateData(data, false, true, this.editBtn.getAttribute('href')); @@ -172,20 +171,20 @@ export class EncryptDecryptManager extends Component { const link = element.getAttribute('href'); const response = await this.openDialog(); if (response) { - const password = this.encryptDialog.querySelector('#page-encrypt-password').value; + const decryptPassword = this.encryptDialog.querySelector('#page-encrypt-password').value; - window.$http.post(`${this.url}/validate-password`, {decrypt_password: password}).then(async resp => { + window.$http.post(`${this.url}/validate-password`, {password: decryptPassword}).then(async resp => { if (resp.data.success) { const data = { is_decrypt: 'FOR_EXPORT', - decrypt_password: password, + password: decryptPassword, }; this.updateData(data, false, true, link); } else { this.invalidPassword.innerHTML = 'Invalid Password'; this.invalidPassword.classList.remove('hidden'); - this.decryptForExport(event); + this.decryptForExport(event, element); } }); } diff --git a/tests/Entity/PageTest.php b/tests/Entity/PageTest.php index fad002be7da..9c4609dac1f 100644 --- a/tests/Entity/PageTest.php +++ b/tests/Entity/PageTest.php @@ -375,7 +375,7 @@ public function test_page_encryption() $data = [ 'html' => $encryptedHtml, - 'decrypt_password' => 'BlaBLa@123', + 'password' => 'BlaBLa@123', 'is_encrypted' => true, ]; @@ -415,7 +415,7 @@ public function test_page_decryption() // Update Encrypt Data $data = [ 'html' => $encryptedHtml, - 'decrypt_password' => $decryptPassword, + 'password' => $decryptPassword, 'is_encrypted' => true, ]; @@ -425,7 +425,7 @@ public function test_page_decryption() // Decrypt The Page Content $decryptData = [ - 'decrypt_password' => $decryptPassword, + 'password' => $decryptPassword, 'content' => $page->html, ]; @@ -439,7 +439,7 @@ public function test_page_decryption() $decryptData = [ 'html' => $pageDecryptResp->json('content'), 'is_encrypted' => false, - 'decrypt_password' => $decryptPassword, + 'password' => $decryptPassword, ]; $pageDecryptUpdateResponse = $this->put("$url/update-decryption", $decryptData); From 805461955158aaabdca1df1e6b6f180f73fd9b24 Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Wed, 4 Dec 2024 19:26:54 +0530 Subject: [PATCH 06/10] Fix Lint PHP --- ...30801_rename_decrypt_password_to_password_in_pages_table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php b/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php index 8a035d5f2bb..18985df298c 100755 --- a/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php +++ b/database/migrations/2024_12_04_130801_rename_decrypt_password_to_password_in_pages_table.php @@ -12,7 +12,7 @@ public function up(): void { Schema::table('pages', function (Blueprint $table) { - $table->renameColumn('decrypt_password','password'); + $table->renameColumn('decrypt_password', 'password'); }); } From 05ae8a2805e8ce5ae178be77d4638cc9a6c19815 Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Thu, 5 Dec 2024 10:54:26 +0530 Subject: [PATCH 07/10] "Add descriptions for encryption and decryption in different languages." --- lang/ar/common.php | 4 ++++ lang/bg/common.php | 5 +++++ lang/bs/common.php | 4 ++++ lang/ca/common.php | 4 ++++ lang/cs/common.php | 5 +++++ lang/cy/common.php | 4 ++++ lang/da/common.php | 4 ++++ lang/de/common.php | 4 ++++ lang/de_informal/common.php | 4 ++++ lang/el/common.php | 4 ++++ lang/en/common.php | 3 ++- lang/es/common.php | 4 ++++ lang/es_AR/common.php | 4 ++++ lang/et/common.php | 4 ++++ lang/eu/common.php | 4 ++++ lang/fa/common.php | 4 ++++ lang/fi/common.php | 4 ++++ lang/fr/common.php | 4 ++++ lang/he/common.php | 4 ++++ lang/hr/common.php | 4 ++++ lang/hu/common.php | 4 ++++ lang/id/common.php | 4 ++++ lang/it/common.php | 4 ++++ lang/ja/common.php | 4 ++++ lang/ko/common.php | 4 ++++ lang/lt/common.php | 4 ++++ lang/lv/common.php | 4 ++++ lang/nb/common.php | 4 ++++ lang/nl/common.php | 4 ++++ lang/nn/common.php | 4 ++++ lang/pl/common.php | 4 ++++ lang/pt/common.php | 4 ++++ lang/pt_BR/common.php | 4 ++++ lang/ro/common.php | 4 ++++ lang/ru/common.php | 4 ++++ lang/sk/common.php | 4 ++++ lang/sl/common.php | 4 ++++ lang/sv/common.php | 4 ++++ lang/tr/common.php | 4 ++++ lang/uk/common.php | 4 ++++ lang/uz/common.php | 4 ++++ lang/vi/common.php | 4 ++++ lang/zh_CN/common.php | 4 ++++ lang/zh_TW/common.php | 4 ++++ resources/views/pages/show.blade.php | 15 ++++++++++++--- 45 files changed, 188 insertions(+), 4 deletions(-) diff --git a/lang/ar/common.php b/lang/ar/common.php index 454b36a9448..e27ccefcf73 100644 --- a/lang/ar/common.php +++ b/lang/ar/common.php @@ -53,6 +53,10 @@ 'download' => 'تنزيل', 'open_in_tab' => 'فتح في علامة تبويب', 'open' => 'فتح', + 'encrypt' => 'تشفير', + 'encrypt_desc' => 'أدخل كلمة مرور للتشفير وتذكرها لعرض المحتوى أو فك تشفيره.', + 'decrypt' => 'فك التشفير', + 'decrypt_desc' => 'أدخل كلمة مرور لفك التشفير.', // Sort Options 'sort_options' => 'خيارات الفرز', diff --git a/lang/bg/common.php b/lang/bg/common.php index 30298e63941..ee2bff917df 100644 --- a/lang/bg/common.php +++ b/lang/bg/common.php @@ -53,6 +53,11 @@ 'download' => 'Изтегляне', 'open_in_tab' => 'Отваряне в раздел', 'open' => 'Open', + 'encrypt' => 'Криптиране', + 'encrypt_desc' => 'Въведете парола за криптиране и я запомнете, за да видите или декриптирате съдържанието.', + 'decrypt' => 'Декриптиране', + 'decrypt_desc' => 'Въведете парола за декриптиране.', + // Sort Options 'sort_options' => 'Опции за сортиране', diff --git a/lang/bs/common.php b/lang/bs/common.php index 4e4631a0d9d..d09e1402d1c 100644 --- a/lang/bs/common.php +++ b/lang/bs/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', + 'encrypt' => 'Šifriranje', + 'encrypt_desc' => 'Unesite lozinku za šifriranje i zapamtite je kako biste vidjeli ili dešifrirali sadržaj.', + 'decrypt' => 'Dešifriranje', + 'decrypt_desc' => 'Unesite lozinku za dešifriranje.', // Sort Options 'sort_options' => 'Opcije sortiranja', diff --git a/lang/ca/common.php b/lang/ca/common.php index f4ad19230b7..3dad554b623 100644 --- a/lang/ca/common.php +++ b/lang/ca/common.php @@ -53,6 +53,10 @@ 'download' => 'Baixa', 'open_in_tab' => 'Obre en una pestanya', 'open' => 'Obre', + 'encrypt' => 'Encriptar', + 'encrypt_desc' => 'Introduïu una contrasenya per a l’encriptació i recordeu-la per veure o desencriptar el contingut.', + 'decrypt' => 'Desencriptar', + 'decrypt_desc' => 'Introduïu una contrasenya per desencriptar.', // Sort Options 'sort_options' => 'Opcions d’ordenació', diff --git a/lang/cs/common.php b/lang/cs/common.php index 1e20b17e7dc..5c600276297 100644 --- a/lang/cs/common.php +++ b/lang/cs/common.php @@ -53,6 +53,11 @@ 'download' => 'Stáhnout', 'open_in_tab' => 'Otevřít v nové záložce', 'open' => 'Otevřít', + 'encrypt' => 'Šifrovat', + 'encrypt_desc' => 'Zadejte heslo pro šifrování a zapamatujte si ho pro zobrazení nebo dešifrování obsahu.', + 'decrypt' => 'Dešifrovat', + 'decrypt_desc' => 'Zadejte heslo pro dešifrování.', + // Sort Options 'sort_options' => 'Možnosti řazení', diff --git a/lang/cy/common.php b/lang/cy/common.php index c8c770b7118..15aa25c441b 100644 --- a/lang/cy/common.php +++ b/lang/cy/common.php @@ -53,6 +53,10 @@ 'download' => 'Llwytho i lawr', 'open_in_tab' => 'Agor mewn Tab', 'open' => 'Agor', + 'encrypt' => 'Amgryptio', + 'encrypt_desc' => 'Rhowch gyfrinair i amgryptio a’i gofio i weld neu ddatgryptio’r cynnwys.', + 'decrypt' => 'Dadgryptio', + 'decrypt_desc' => 'Rhowch gyfrinair i ddatgryptio.', // Sort Options 'sort_options' => 'Trefnu\'r opsiynau', diff --git a/lang/da/common.php b/lang/da/common.php index 75060b28b3f..e15b9e67bc1 100644 --- a/lang/da/common.php +++ b/lang/da/common.php @@ -53,6 +53,10 @@ 'download' => 'Hent', 'open_in_tab' => 'Åben i ny fane', 'open' => 'Åbn', + 'encrypt' => 'Krypter', + 'encrypt_desc' => 'Indtast en adgangskode til kryptering, og husk den for at se eller dekryptere indholdet.', + 'decrypt' => 'Dekrypter', + 'decrypt_desc' => 'Indtast en adgangskode til dekryptering.', // Sort Options 'sort_options' => 'Sorteringsindstillinger', diff --git a/lang/de/common.php b/lang/de/common.php index 8ff91da0a25..458aa0d07b1 100644 --- a/lang/de/common.php +++ b/lang/de/common.php @@ -53,6 +53,10 @@ 'download' => 'Herunterladen', 'open_in_tab' => 'In neuem Tab öffnen', 'open' => 'Öffnen', + 'encrypt' => 'Verschlüsseln', + 'encrypt_desc' => 'Geben Sie ein Passwort zur Verschlüsselung ein und merken Sie es sich, um den Inhalt anzuzeigen oder zu entschlüsseln.', + 'decrypt' => 'Entschlüsseln', + 'decrypt_desc' => 'Geben Sie ein Passwort zur Entschlüsselung ein.', // Sort Options 'sort_options' => 'Sortieroptionen', diff --git a/lang/de_informal/common.php b/lang/de_informal/common.php index e033b63d22e..e4da838df79 100644 --- a/lang/de_informal/common.php +++ b/lang/de_informal/common.php @@ -53,6 +53,10 @@ 'download' => 'Herunterladen', 'open_in_tab' => 'In Tab öffnen', 'open' => 'Öffnen', + 'encrypt' => 'Verschlüsseln', + 'encrypt_desc' => 'Geben Sie ein Passwort zur Verschlüsselung ein und merken Sie es sich, um den Inhalt anzuzeigen oder zu entschlüsseln.', + 'decrypt' => 'Entschlüsseln', + 'decrypt_desc' => 'Geben Sie ein Passwort zur Entschlüsselung ein.', // Sort Options 'sort_options' => 'Sortieroptionen', diff --git a/lang/el/common.php b/lang/el/common.php index d1b6bd9f790..c0319815c37 100644 --- a/lang/el/common.php +++ b/lang/el/common.php @@ -53,6 +53,10 @@ 'download' => 'Λήψη', 'open_in_tab' => 'Άνοιγμα σε Καρτέλα', 'open' => 'Open', + 'encrypt' => 'Κρυπτογράφηση', + 'encrypt_desc' => 'Εισαγάγετε έναν κωδικό πρόσβασης για κρυπτογράφηση και θυμηθείτε τον για να δείτε ή να αποκρυπτογραφήσετε το περιεχόμενο.', + 'decrypt' => 'Αποκρυπτογράφηση', + 'decrypt_desc' => 'Εισαγάγετε έναν κωδικό πρόσβασης για αποκρυπτογράφηση.', // Sort Options 'sort_options' => 'Επιλογές ταξινόμησης', diff --git a/lang/en/common.php b/lang/en/common.php index 9517d41b173..92128866c86 100644 --- a/lang/en/common.php +++ b/lang/en/common.php @@ -53,9 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', - 'restrict' => 'Restrict', 'encrypt' => 'Encrypt', + 'encrypt_desc' => 'Enter a password for encryption and remember it to view or decrypt the content', 'decrypt' => 'Decrypt', + 'decrypt_desc' => 'Enter a Password For Decryption', // Sort Options 'sort_options' => 'Sort Options', diff --git a/lang/es/common.php b/lang/es/common.php index 14eee82d97c..232dcd5c0ff 100644 --- a/lang/es/common.php +++ b/lang/es/common.php @@ -53,6 +53,10 @@ 'download' => 'Descargar', 'open_in_tab' => 'Abrir en una nueva pestaña', 'open' => 'Abrir', + 'encrypt' => 'Encriptar', + 'encrypt_desc' => 'Ingrese una contraseña para la encriptación y recuérdela para ver o desencriptar el contenido.', + 'decrypt' => 'Desencriptar', + 'decrypt_desc' => 'Ingrese una contraseña para desencriptar.', // Sort Options 'sort_options' => 'Opciones de ordenación', diff --git a/lang/es_AR/common.php b/lang/es_AR/common.php index ebac11119d3..4d3a6364590 100644 --- a/lang/es_AR/common.php +++ b/lang/es_AR/common.php @@ -53,6 +53,10 @@ 'download' => 'Descargar', 'open_in_tab' => 'Abrir en una pestaña', 'open' => 'Abrir', + 'encrypt' => 'Encriptar', + 'encrypt_desc' => 'Ingrese una contraseña para encriptar y recuérdela para ver o desencriptar el contenido.', + 'decrypt' => 'Desencriptar', + 'decrypt_desc' => 'Ingrese una contraseña para desencriptar.', // Sort Options 'sort_options' => 'Opciones de Orden', diff --git a/lang/et/common.php b/lang/et/common.php index a53060a00e6..d8c44990f18 100644 --- a/lang/et/common.php +++ b/lang/et/common.php @@ -53,6 +53,10 @@ 'download' => 'Laadi alla', 'open_in_tab' => 'Ava vahelehel', 'open' => 'Ava', + 'encrypt' => 'Krüpteeri', + 'encrypt_desc' => 'Sisestage krüpteerimiseks parool ja jätke see meelde, et sisu vaadata või dekrüpteerida.', + 'decrypt' => 'Dekrüpteeri', + 'decrypt_desc' => 'Sisestage parool dekrüpteerimiseks.', // Sort Options 'sort_options' => 'Sorteerimise valikud', diff --git a/lang/eu/common.php b/lang/eu/common.php index 35a67b349ab..4bdc3f5c237 100644 --- a/lang/eu/common.php +++ b/lang/eu/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', + 'encrypt' => 'Zifratzea', + 'encrypt_desc' => 'Sartu zifratze pasahitza eta gorde edukia ikusteko edo deszifratzeko.', + 'decrypt' => 'Deszifratu', + 'decrypt_desc' => 'Sartu deszifratzeko pasahitza.', // Sort Options 'sort_options' => 'Ordenatzeko aukerak', diff --git a/lang/fa/common.php b/lang/fa/common.php index 765c1e6271d..d5e5ba435df 100644 --- a/lang/fa/common.php +++ b/lang/fa/common.php @@ -53,6 +53,10 @@ 'download' => 'دانلود', 'open_in_tab' => 'باز کردن در تب جدید', 'open' => 'بازکردن', + 'encrypt' => 'رمزگذاری', + 'encrypt_desc' => 'یک رمز عبور برای رمزگذاری وارد کنید و آن را برای مشاهده یا رمزگشایی محتوا به خاطر بسپارید.', + 'decrypt' => 'رمزگشایی', + 'decrypt_desc' => 'یک رمز عبور برای رمزگشایی وارد کنید.', // Sort Options 'sort_options' => 'گزینه‌های مرتب سازی', diff --git a/lang/fi/common.php b/lang/fi/common.php index d6efe8e0347..168d44efbb5 100644 --- a/lang/fi/common.php +++ b/lang/fi/common.php @@ -53,6 +53,10 @@ 'download' => 'Lataa', 'open_in_tab' => 'Avaa välilehdessä', 'open' => 'Avaa', + 'encrypt' => 'Salaus', + 'encrypt_desc' => 'Anna salaus salasana ja muista se nähdäksesi tai purkaaksesi sisällön salauksen.', + 'decrypt' => 'Pura salaus', + 'decrypt_desc' => 'Anna salauksen purkamisen salasana.', // Sort Options 'sort_options' => 'Järjestyksen asetukset', diff --git a/lang/fr/common.php b/lang/fr/common.php index 282a72e4569..e5afd555f96 100644 --- a/lang/fr/common.php +++ b/lang/fr/common.php @@ -53,6 +53,10 @@ 'download' => 'Télécharger', 'open_in_tab' => 'Ouvrir dans un onglet', 'open' => 'Ouvert', + 'encrypt' => 'Crypter', + 'encrypt_desc' => 'Entrez un mot de passe pour le cryptage et mémorisez-le pour afficher ou décrypter le contenu.', + 'decrypt' => 'Décrypter', + 'decrypt_desc' => 'Entrez un mot de passe pour décrypter.', // Sort Options 'sort_options' => 'Options de tri', diff --git a/lang/he/common.php b/lang/he/common.php index a427df954fe..c469fe43545 100644 --- a/lang/he/common.php +++ b/lang/he/common.php @@ -53,6 +53,10 @@ 'download' => 'הורדה', 'open_in_tab' => 'פתח בכרטיסייה חדשה', 'open' => 'Open', + 'encrypt' => 'הצפנה', + 'encrypt_desc' => 'הזן סיסמה להצפנה וזכור אותה כדי לצפות או לפענח את התוכן.', + 'decrypt' => 'פענוח', + 'decrypt_desc' => 'הזן סיסמה לפענוח.', // Sort Options 'sort_options' => 'אפשרויות מיון', diff --git a/lang/hr/common.php b/lang/hr/common.php index 3c9ed610bc6..992ae209c9e 100644 --- a/lang/hr/common.php +++ b/lang/hr/common.php @@ -53,6 +53,10 @@ 'download' => 'Preuzmi', 'open_in_tab' => 'Otvori u Kartici', 'open' => 'Open', + 'encrypt' => 'Šifriraj', + 'encrypt_desc' => 'Unesite lozinku za šifriranje i zapamtite je kako biste mogli pregledati ili dešifrirati sadržaj.', + 'decrypt' => 'Dešifriraj', + 'decrypt_desc' => 'Unesite lozinku za dešifriranje.', // Sort Options 'sort_options' => 'Razvrstaj opcije', diff --git a/lang/hu/common.php b/lang/hu/common.php index 29a87e19edf..11ace29d362 100644 --- a/lang/hu/common.php +++ b/lang/hu/common.php @@ -53,6 +53,10 @@ 'download' => 'Letöltés', 'open_in_tab' => 'Megnyitás új tab-on', 'open' => 'Megnyitás', + 'encrypt' => 'Titkosítás', + 'encrypt_desc' => 'Adjon meg egy jelszót a titkosításhoz, és jegyezze meg, hogy megtekinthesse vagy visszafejthesse a tartalmat.', + 'decrypt' => 'Dekódolás', + 'decrypt_desc' => 'Adjon meg egy jelszót a dekódoláshoz.', // Sort Options 'sort_options' => 'Rendezési beállítások', diff --git a/lang/id/common.php b/lang/id/common.php index 06e9421c87b..a9876aaaf11 100644 --- a/lang/id/common.php +++ b/lang/id/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', + 'encrypt' => 'Enkripsi', + 'encrypt_desc' => 'Masukkan kata sandi untuk enkripsi dan ingat untuk melihat atau mendekripsi konten.', + 'decrypt' => 'Dekripsi', + 'decrypt_desc' => 'Masukkan kata sandi untuk dekripsi.', // Sort Options 'sort_options' => 'Opsi Sortir', diff --git a/lang/it/common.php b/lang/it/common.php index 113ddb01405..d1a67d44afe 100644 --- a/lang/it/common.php +++ b/lang/it/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Apri nella scheda', 'open' => 'Apri', + 'encrypt' => 'Criptare', + 'encrypt_desc' => 'Inserisci una password per la crittografia e ricordala per visualizzare o decriptare il contenuto.', + 'decrypt' => 'Decriptare', + 'decrypt_desc' => 'Inserisci una password per decriptare.', // Sort Options 'sort_options' => 'Opzioni Ordinamento', diff --git a/lang/ja/common.php b/lang/ja/common.php index 097974d8e96..a0b3398d7fe 100644 --- a/lang/ja/common.php +++ b/lang/ja/common.php @@ -53,6 +53,10 @@ 'download' => 'ダウンロード', 'open_in_tab' => 'タブで開く', 'open' => '開く', + 'encrypt' => '暗号化', + 'encrypt_desc' => '暗号化のためのパスワードを入力し、それを覚えておいてコンテンツを表示または復号してください。', + 'decrypt' => '復号化', + 'decrypt_desc' => '復号化するためのパスワードを入力してください。', // Sort Options 'sort_options' => '並べ替えオプション', diff --git a/lang/ko/common.php b/lang/ko/common.php index 246a3aebc36..ac114be79d7 100644 --- a/lang/ko/common.php +++ b/lang/ko/common.php @@ -53,6 +53,10 @@ 'download' => '내려받기', 'open_in_tab' => '탭에서 열기', 'open' => '열기 ', + 'encrypt' => '암호화', + 'encrypt_desc' => '암호화를 위해 비밀번호를 입력하고 내용을 보거나 해독하려면 기억하세요.', + 'decrypt' => '복호화', + 'decrypt_desc' => '복호화를 위해 비밀번호를 입력하세요.', // Sort Options 'sort_options' => '정렬 기준', diff --git a/lang/lt/common.php b/lang/lt/common.php index e375c835ceb..d4a1f2ea318 100644 --- a/lang/lt/common.php +++ b/lang/lt/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', + 'encrypt' => 'Užšifruoti', + 'encrypt_desc' => 'Įveskite slaptažodį šifravimui ir prisiminkite jį, kad galėtumėte peržiūrėti arba iššifruoti turinį.', + 'decrypt' => 'Iššifruoti', + 'decrypt_desc' => 'Įveskite slaptažodį iššifravimui.', // Sort Options 'sort_options' => 'Rūšiuoti pasirinkimus', diff --git a/lang/lv/common.php b/lang/lv/common.php index 584b24cb2e7..95568b0427d 100644 --- a/lang/lv/common.php +++ b/lang/lv/common.php @@ -53,6 +53,10 @@ 'download' => 'Lejupielādēt', 'open_in_tab' => 'Atvērt cilnē', 'open' => 'Atvērt', + 'encrypt' => 'Šifrēt', + 'encrypt_desc' => 'Ievadiet paroli šifrēšanai un atcerieties to, lai skatītu vai atšifrētu saturu.', + 'decrypt' => 'Atšifrēt', + 'decrypt_desc' => 'Ievadiet paroli atšifrēšanai.', // Sort Options 'sort_options' => 'Kārtošanas Opcijas', diff --git a/lang/nb/common.php b/lang/nb/common.php index 0e9e19b6e59..33042ae670d 100644 --- a/lang/nb/common.php +++ b/lang/nb/common.php @@ -53,6 +53,10 @@ 'download' => 'Last ned', 'open_in_tab' => 'Åpne i fane', 'open' => 'Åpne', + 'encrypt' => 'Krypter', + 'encrypt_desc' => 'Skriv inn et passord for kryptering, og husk det for å se eller dekryptere innholdet.', + 'decrypt' => 'Dekrypter', + 'decrypt_desc' => 'Skriv inn et passord for dekryptering.', // Sort Options 'sort_options' => 'Sorteringsalternativer', diff --git a/lang/nl/common.php b/lang/nl/common.php index 844fe91d1af..7fa08579865 100644 --- a/lang/nl/common.php +++ b/lang/nl/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open als Tabblad', 'open' => 'Open', + 'encrypt' => 'Versleutelen', + 'encrypt_desc' => 'Voer een wachtwoord in voor versleuteling en onthoud het om de inhoud te bekijken of te ontsleutelen.', + 'decrypt' => 'Ontsleutelen', + 'decrypt_desc' => 'Voer een wachtwoord in om te ontsleutelen.', // Sort Options 'sort_options' => 'Sorteeropties', diff --git a/lang/nn/common.php b/lang/nn/common.php index 3d623dbc492..4d4d8da862b 100644 --- a/lang/nn/common.php +++ b/lang/nn/common.php @@ -53,6 +53,10 @@ 'download' => 'Last ned', 'open_in_tab' => 'Opne i fane', 'open' => 'Opne', + 'encrypt' => 'Krypter', + 'encrypt_desc' => 'Skriv inn eit passord for kryptering, og hugs det for å sjå eller dekryptere innhaldet.', + 'decrypt' => 'Dekrypter', + 'decrypt_desc' => 'Skriv inn eit passord for dekryptering.', // Sort Options 'sort_options' => 'Sorteringsalternativ', diff --git a/lang/pl/common.php b/lang/pl/common.php index 4d5a346b2b5..d3f5ed727c9 100644 --- a/lang/pl/common.php +++ b/lang/pl/common.php @@ -53,6 +53,10 @@ 'download' => 'Pobierz', 'open_in_tab' => 'Otwórz w karcie', 'open' => 'Otwórz', + 'encrypt' => 'Szyfrować', + 'encrypt_desc' => 'Wprowadź hasło do szyfrowania i zapamiętaj je, aby wyświetlić lub odszyfrować zawartość.', + 'decrypt' => 'Odszyfrować', + 'decrypt_desc' => 'Wprowadź hasło do odszyfrowania.', // Sort Options 'sort_options' => 'Opcje sortowania', diff --git a/lang/pt/common.php b/lang/pt/common.php index 3e005700245..53028f3e973 100644 --- a/lang/pt/common.php +++ b/lang/pt/common.php @@ -53,6 +53,10 @@ 'download' => 'Transferir', 'open_in_tab' => 'Abrir em novo separador', 'open' => 'Abrir', + 'encrypt' => 'Criptografar', + 'encrypt_desc' => 'Digite uma senha para criptografar e lembre-se dela para visualizar ou descriptografar o conteúdo.', + 'decrypt' => 'Descriptografar', + 'decrypt_desc' => 'Digite uma senha para descriptografar.', // Sort Options 'sort_options' => 'Opções de Ordenação', diff --git a/lang/pt_BR/common.php b/lang/pt_BR/common.php index f5e6d230d43..846c59c6661 100644 --- a/lang/pt_BR/common.php +++ b/lang/pt_BR/common.php @@ -58,6 +58,10 @@ 'download' => 'Baixar ', 'open_in_tab' => 'Abrir na aba', 'open' => 'Abrir', + 'encrypt' => 'Criptografar', + 'encrypt_desc' => 'Digite uma senha para criptografar e lembre-se dela para visualizar ou descriptografar o conteúdo.', + 'decrypt' => 'Descriptografar', + 'decrypt_desc' => 'Digite uma senha para descriptografar.', // Sort Options 'sort_options' => 'Opções de Ordenação', diff --git a/lang/ro/common.php b/lang/ro/common.php index 1de631183f6..9a7bd9172df 100644 --- a/lang/ro/common.php +++ b/lang/ro/common.php @@ -53,6 +53,10 @@ 'download' => 'Descarcă', 'open_in_tab' => 'Deschide in tab', 'open' => 'Open', + 'encrypt' => 'Criptare', + 'encrypt_desc' => 'Introduceți o parolă pentru criptare și rețineți-o pentru a vizualiza sau decripta conținutul.', + 'decrypt' => 'Decriptare', + 'decrypt_desc' => 'Introduceți o parolă pentru decriptare.', // Sort Options 'sort_options' => 'Opțiuni ordonare', diff --git a/lang/ru/common.php b/lang/ru/common.php index d3860bba461..a15eaa9425e 100644 --- a/lang/ru/common.php +++ b/lang/ru/common.php @@ -53,6 +53,10 @@ 'download' => 'Загрузить', 'open_in_tab' => 'Открыть во вкладке', 'open' => 'Открыть', + 'encrypt' => 'Шифрование', + 'encrypt_desc' => 'Введите пароль для шифрования и запомните его, чтобы просматривать или расшифровывать содержимое.', + 'decrypt' => 'Расшифровка', + 'decrypt_desc' => 'Введите пароль для расшифровки.', // Sort Options 'sort_options' => 'Параметры сортировки', diff --git a/lang/sk/common.php b/lang/sk/common.php index 12828d6c2e5..9a190aa7440 100644 --- a/lang/sk/common.php +++ b/lang/sk/common.php @@ -53,6 +53,10 @@ 'download' => 'Stiahnuť', 'open_in_tab' => 'Otvoriť na novej karte', 'open' => 'Open', + 'encrypt' => 'Šifrovať', + 'encrypt_desc' => 'Zadajte heslo na šifrovanie a zapamätajte si ho, aby ste mohli zobraziť alebo dešifrovať obsah.', + 'decrypt' => 'Dešifrovať', + 'decrypt_desc' => 'Zadajte heslo na dešifrovanie.', // Sort Options 'sort_options' => 'Možnosti triedenia', diff --git a/lang/sl/common.php b/lang/sl/common.php index 4bad22048c6..13079b101ed 100644 --- a/lang/sl/common.php +++ b/lang/sl/common.php @@ -53,6 +53,10 @@ 'download' => 'Download', 'open_in_tab' => 'Open in Tab', 'open' => 'Open', + 'encrypt' => 'Šifriraj', + 'encrypt_desc' => 'Vnesite geslo za šifriranje in si ga zapomnite, da si boste lahko ogledali ali dešifrirali vsebino.', + 'decrypt' => 'Dešifriraj', + 'decrypt_desc' => 'Vnesite geslo za dešifriranje.', // Sort Options 'sort_options' => 'Možnosti razvrščanja', diff --git a/lang/sv/common.php b/lang/sv/common.php index 8fe80899f0e..824e3df433d 100644 --- a/lang/sv/common.php +++ b/lang/sv/common.php @@ -53,6 +53,10 @@ 'download' => 'Ladda ner', 'open_in_tab' => 'Öppna i flik', 'open' => 'Öppna', + 'encrypt' => 'Kryptera', + 'encrypt_desc' => 'Ange ett lösenord för kryptering och kom ihåg det för att visa eller dekryptera innehållet.', + 'decrypt' => 'Dekryptera', + 'decrypt_desc' => 'Ange ett lösenord för dekryptering.', // Sort Options 'sort_options' => 'Sorteringsalternativ', diff --git a/lang/tr/common.php b/lang/tr/common.php index 3e416d37bfc..543937d1a1d 100644 --- a/lang/tr/common.php +++ b/lang/tr/common.php @@ -53,6 +53,10 @@ 'download' => 'İndir', 'open_in_tab' => 'Sekmede aç', 'open' => 'Open', + 'encrypt' => 'Şifrele', + 'encrypt_desc' => 'Şifreleme için bir parola girin ve içeriği görüntülemek veya şifresini çözmek için hatırlayın.', + 'decrypt' => 'Şifre Çöz', + 'decrypt_desc' => 'Şifre çözme için bir parola girin.', // Sort Options 'sort_options' => 'Sıralama Seçenekleri', diff --git a/lang/uk/common.php b/lang/uk/common.php index d384e392447..04c56cd4b75 100644 --- a/lang/uk/common.php +++ b/lang/uk/common.php @@ -53,6 +53,10 @@ 'download' => 'Завантажити', 'open_in_tab' => 'Відкрити в новій вкладці', 'open' => 'Відкрити', + 'encrypt' => 'Шифрувати', + 'encrypt_desc' => 'Введіть пароль для шифрування і запам’ятайте його, щоб переглядати або дешифрувати вміст.', + 'decrypt' => 'Розшифрувати', + 'decrypt_desc' => 'Введіть пароль для розшифрування.', // Sort Options 'sort_options' => 'Параметри сортування', diff --git a/lang/uz/common.php b/lang/uz/common.php index fcbb2ea84a8..89d81de73f7 100644 --- a/lang/uz/common.php +++ b/lang/uz/common.php @@ -53,6 +53,10 @@ 'download' => 'Yuklab olish', 'open_in_tab' => 'Tabda ochish', 'open' => 'Open', + 'encrypt' => 'Shifrlash', + 'encrypt_desc' => 'Shifrlash uchun parolni kiriting va mazmunni ko‘rish yoki shifrdan chiqarish uchun uni eslab qoling.', + 'decrypt' => 'Shifrdan chiqarish', + 'decrypt_desc' => 'Shifrdan chiqarish uchun parolni kiriting.', // Sort Options 'sort_options' => 'Saralash opsiyalari', diff --git a/lang/vi/common.php b/lang/vi/common.php index 16929a2fbae..38991ebfffa 100644 --- a/lang/vi/common.php +++ b/lang/vi/common.php @@ -53,6 +53,10 @@ 'download' => 'Tải về', 'open_in_tab' => 'Mở trong thẻ mới', 'open' => 'Open', + 'encrypt' => 'Mã hóa', + 'encrypt_desc' => 'Nhập mật khẩu để mã hóa và nhớ nó để xem hoặc giải mã nội dung.', + 'decrypt' => 'Giải mã', + 'decrypt_desc' => 'Nhập mật khẩu để giải mã.', // Sort Options 'sort_options' => 'Tùy Chọn Sắp Xếp', diff --git a/lang/zh_CN/common.php b/lang/zh_CN/common.php index bc391354e69..832621df8b6 100644 --- a/lang/zh_CN/common.php +++ b/lang/zh_CN/common.php @@ -53,6 +53,10 @@ 'download' => '下载', 'open_in_tab' => '在标签页中打开。', 'open' => '打开', + 'encrypt' => '加密', + 'encrypt_desc' => '输入密码进行加密,并记住它以查看或解密内容。', + 'decrypt' => '解密', + 'decrypt_desc' => '输入密码进行解密。', // Sort Options 'sort_options' => '排序选项', diff --git a/lang/zh_TW/common.php b/lang/zh_TW/common.php index 8b003a7303b..c67b07b8ea9 100644 --- a/lang/zh_TW/common.php +++ b/lang/zh_TW/common.php @@ -53,6 +53,10 @@ 'download' => '下載', 'open_in_tab' => '在新分頁中開啟', 'open' => '開啟', + 'encrypt' => '加密', + 'encrypt_desc' => '輸入密碼進行加密,並記住它以檢視或解密內容。', + 'decrypt' => '解密', + 'decrypt_desc' => '輸入密碼進行解密。', // Sort Options 'sort_options' => '排序選項', diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php index 056d5c52fb1..65022a65441 100644 --- a/resources/views/pages/show.blade.php +++ b/resources/views/pages/show.blade.php @@ -8,10 +8,19 @@ @section('body') @component('common.confirm-dialog', ['title' => trans($page->is_encrypted ? 'common.decrypt' : 'common.encrypt'), 'class' => 'encrypt-decrypt-dialog mt-xl']) +
+
+ +

{{ trans($page->is_encrypted ? 'common.decrypt_desc' : 'common.encrypt_desc') }}

+
+
+ +
+ +
+

- -
- +

@endcomponent +

{{ trans('common.decrypt_desc') }}

From 8163d9b0eccb974bd88f4214f13bfcb80fed7372 Mon Sep 17 00:00:00 2001 From: Brij Mandaliya Date: Thu, 5 Dec 2024 15:07:22 +0530 Subject: [PATCH 10/10] "Give Message if password length is less than 6" --- .../js/components/encrypt-decrypt-manager.js | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/resources/js/components/encrypt-decrypt-manager.js b/resources/js/components/encrypt-decrypt-manager.js index 0b908053da8..5de19858259 100644 --- a/resources/js/components/encrypt-decrypt-manager.js +++ b/resources/js/components/encrypt-decrypt-manager.js @@ -83,19 +83,16 @@ export class EncryptDecryptManager extends Component { } } - decryptContent(decryptPassword, updateDecryption = false) { + async decryptContent(decryptPassword, updateDecryption = false) { if (decryptPassword.length > 6) { - if(this.is_decrypt && updateDecryption) - { + if (this.is_decrypt && updateDecryption) { const decryptData = { html: this.pageDetailContent.innerHTML, is_encrypted: false, password: decryptPassword, }; this.updateData(decryptData, false, false); - } - else - { + } else { const decryptData = { content: this.pageDetailContent.innerHTML, password: decryptPassword, @@ -103,7 +100,7 @@ export class EncryptDecryptManager extends Component { window.$http.post(`${this.url}/decrypt`, decryptData).then(async resp => { if (resp.data.success) { this.decryptPassword.value = ''; - + if (updateDecryption) { const data = { html: resp.data.content, @@ -116,21 +113,29 @@ export class EncryptDecryptManager extends Component { this.is_decrypt = true; this.encryptInfo.classList.add('hidden'); } - } else { - if (updateDecryption) { - this.invalidPassword.innerHTML = resp.data.message; - this.invalidPassword.classList.remove('hidden'); - const response = await this.openDialog(); - if (response) { - this.decryptContent(this.passwordInput.value, updateDecryption); - } - } else { - this.invalidMsg.innerHTML = resp.data.message; - this.invalidMsg.classList.remove('hidden'); + } else if (updateDecryption) { + this.invalidPassword.innerHTML = resp.data.message; + this.invalidPassword.classList.remove('hidden'); + const response = await this.openDialog(); + if (response) { + this.decryptContent(this.passwordInput.value, updateDecryption); } + } else { + this.invalidMsg.innerHTML = resp.data.message; + this.invalidMsg.classList.remove('hidden'); } }); } + } else if (updateDecryption) { + this.invalidPassword.innerHTML = 'Password Length Should be More Than 6'; + this.invalidPassword.classList.remove('hidden'); + const response = await this.openDialog(); + if (response) { + this.decryptContent(this.passwordInput.value, updateDecryption); + } + } else { + this.invalidMsg.innerHTML = 'Password Length Should be More Than 6'; + this.invalidMsg.classList.remove('hidden'); } }