├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github ├── release-drafter.yml └── workflows │ ├── client-feedback.yml │ ├── publish-docs.yml │ ├── publish-node.yml │ ├── release-drafter.yml │ └── release-uwp.yml ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── .gitignore ├── .vuepress │ ├── config.ts │ ├── public │ │ ├── CNAME │ │ ├── baidu_verify_code-VFp5HmU9au.html │ │ ├── logo.png │ │ ├── logo_bw.png │ │ ├── logo_wb.png │ │ ├── manifest.json │ │ └── screenshots │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ └── 4.png │ └── styles │ │ └── palette.styl ├── donate.md ├── index.md ├── package.json ├── pp │ ├── en.md │ └── zh.md ├── usage │ ├── api.md │ ├── api │ │ ├── add.png │ │ ├── edit.png │ │ ├── login.png │ │ ├── mng.png │ │ ├── secrets.png │ │ └── url.png │ ├── command.md │ ├── contribute.md │ ├── password.md │ ├── problem.md │ ├── safety.md │ ├── start.md │ ├── start │ │ └── storage.png │ ├── svgicon.md │ ├── svgicon │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ └── 6.png │ ├── sync.md │ └── window.md └── yarn.lock ├── scripts └── client-feedback.js └── src ├── Lavcode.Asp ├── .gitignore ├── Controllers │ ├── AuthController.cs │ ├── FolderController.cs │ └── PasswordController.cs ├── Dockerfile ├── Dtos │ ├── CreateFolderDto.cs │ ├── CreatePasswordDto.cs │ ├── UpdateFolderDto.cs │ ├── UpdatePasswordDto.cs │ ├── UpsertIconDto.cs │ └── UpsertKeyValuePairDto.cs ├── Entities │ ├── DatabaseContext.cs │ ├── FolderEntity.cs │ ├── IconEntity.cs │ ├── KeyValuePairEntity.cs │ └── PasswordEntity.cs ├── Filters │ ├── ErrorFilter.cs │ ├── ExceptionFilter.cs │ └── ValidateFilter.cs ├── Lavcode.Asp.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Services │ └── AuthTokenService.cs ├── appsettings.Development.json └── appsettings.json ├── Lavcode.Common ├── CommonConstant.cs ├── Lavcode.Common.csproj └── RepositoryConstant.cs ├── Lavcode.IService ├── IConService.cs ├── IDataService.cs ├── IFolderService.cs ├── IPasswordService.cs └── Lavcode.IService.csproj ├── Lavcode.Model ├── FolderModel.cs ├── IconModel.cs ├── IconType.cs ├── KeyValuePairModel.cs ├── Lavcode.Model.csproj ├── PasswordModel.cs ├── Provider.cs └── StorageType.cs ├── Lavcode.Service.Api ├── ConService.cs ├── Dtos │ ├── CreateFolderDto.cs │ ├── CreatePasswordDto.cs │ ├── GetFolderDto.cs │ ├── GetIconDto.cs │ ├── GetKeyValuePairDto.cs │ ├── GetPasswordDto.cs │ ├── UpdateFolderDto.cs │ ├── UpdatePasswordDto.cs │ ├── UpsertIconDto.cs │ └── UpsertKeyValuePairDto.cs ├── FolderService.cs ├── Lavcode.Service.Api.csproj └── PasswordService.cs ├── Lavcode.Service.BaseGit ├── BaseGitConService.cs ├── Entities │ ├── FolderEntity.cs │ ├── IEntity.cs │ ├── IconEntity.cs │ ├── KeyValuePairEntity.cs │ └── PasswordEntity.cs ├── FolderService.cs ├── Lavcode.Service.BaseGit.csproj ├── Models │ ├── CommentItem.cs │ ├── IssueItem.cs │ └── RepositoryItem.cs └── PasswordService.cs ├── Lavcode.Service.GitHub ├── GitHubConService.cs └── Lavcode.Service.GitHub.csproj ├── Lavcode.Service.Gitee ├── GiteeConService.cs └── Lavcode.Service.Gitee.csproj ├── Lavcode.Service.Sqlite ├── ConService.cs ├── DelectedService.cs ├── Entities │ ├── BeforeKeyValuePairEntity.cs │ ├── DelectedEntity.cs │ ├── FolderEntity.cs │ ├── IconEntity.cs │ ├── KeyValuePairEntity.cs │ ├── PasswordEntity.cs │ └── TableInfo.cs ├── FolderService.cs ├── Lavcode.Service.Sqlite.csproj ├── PasswordService.cs └── SqliteHelper.cs ├── Lavcode.Uwp ├── .editorconfig ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── Images │ │ ├── Visual │ │ │ ├── BadgeLogo.scale-100.png │ │ │ ├── BadgeLogo.scale-125.png │ │ │ ├── BadgeLogo.scale-150.png │ │ │ ├── BadgeLogo.scale-200.png │ │ │ ├── BadgeLogo.scale-400.png │ │ │ ├── LargeTile.scale-100.png │ │ │ ├── LargeTile.scale-125.png │ │ │ ├── LargeTile.scale-150.png │ │ │ ├── LargeTile.scale-200.png │ │ │ ├── LargeTile.scale-400.png │ │ │ ├── SmallTile.scale-100.png │ │ │ ├── SmallTile.scale-125.png │ │ │ ├── SmallTile.scale-150.png │ │ │ ├── SmallTile.scale-200.png │ │ │ ├── SmallTile.scale-400.png │ │ │ ├── SplashScreen.scale-100.png │ │ │ ├── SplashScreen.scale-125.png │ │ │ ├── SplashScreen.scale-150.png │ │ │ ├── SplashScreen.scale-200.png │ │ │ ├── SplashScreen.scale-400.png │ │ │ ├── Square150x150Logo.scale-100.png │ │ │ ├── Square150x150Logo.scale-125.png │ │ │ ├── Square150x150Logo.scale-150.png │ │ │ ├── Square150x150Logo.scale-200.png │ │ │ ├── Square150x150Logo.scale-400.png │ │ │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png │ │ │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png │ │ │ ├── Square44x44Logo.altform-lightunplated_targetsize-256.png │ │ │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png │ │ │ ├── Square44x44Logo.altform-lightunplated_targetsize-48.png │ │ │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ │ │ ├── Square44x44Logo.altform-unplated_targetsize-24.png │ │ │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ │ │ ├── Square44x44Logo.altform-unplated_targetsize-32.png │ │ │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ │ │ ├── Square44x44Logo.scale-100.png │ │ │ ├── Square44x44Logo.scale-125.png │ │ │ ├── Square44x44Logo.scale-150.png │ │ │ ├── Square44x44Logo.scale-200.png │ │ │ ├── Square44x44Logo.scale-400.png │ │ │ ├── Square44x44Logo.targetsize-16.png │ │ │ ├── Square44x44Logo.targetsize-24.png │ │ │ ├── Square44x44Logo.targetsize-256.png │ │ │ ├── Square44x44Logo.targetsize-32.png │ │ │ ├── Square44x44Logo.targetsize-48.png │ │ │ ├── StoreLogo.scale-100.png │ │ │ ├── StoreLogo.scale-125.png │ │ │ ├── StoreLogo.scale-150.png │ │ │ ├── StoreLogo.scale-200.png │ │ │ ├── StoreLogo.scale-400.png │ │ │ ├── Wide310x150Logo.scale-100.png │ │ │ ├── Wide310x150Logo.scale-125.png │ │ │ ├── Wide310x150Logo.scale-150.png │ │ │ ├── Wide310x150Logo.scale-200.png │ │ │ └── Wide310x150Logo.scale-400.png │ │ ├── alipay.jpg │ │ ├── logo_alpha.png │ │ ├── qq_group.jpg │ │ ├── wechat_qr.png │ │ ├── windows_hello_10.png │ │ ├── windows_hello_11.png │ │ └── wxpay.jpg │ └── StoreLogo.backup.png ├── Controls │ ├── Comment │ │ ├── CommentList.xaml │ │ ├── CommentList.xaml.cs │ │ └── CommentSource.cs │ ├── DialogTitle.xaml │ ├── DialogTitle.xaml.cs │ ├── Header.xaml │ ├── Header.xaml.cs │ ├── Issue │ │ ├── IssueList.xaml │ │ ├── IssueList.xaml.cs │ │ └── IssueSource.cs │ ├── Logo.xaml │ └── Logo.xaml.cs ├── Converters │ └── ProviderConverter.cs ├── Global.cs ├── Helpers │ ├── CommandLauncher.cs │ ├── ExitHandler.cs │ ├── GitHubHelper.cs │ ├── ImgHelper.cs │ ├── NetLoadingHelper.cs │ ├── SettingHelper.cs │ └── UpdateHelper.cs ├── Lavcode.Uwp.csproj ├── Lavcode.Uwp_TemporaryKey.pfx ├── Modules │ ├── Auth │ │ ├── ApiLoginDialog.xaml │ │ ├── ApiLoginDialog.xaml.cs │ │ ├── AuthPage.xaml │ │ ├── AuthPage.xaml.cs │ │ ├── AuthViewModel.cs │ │ ├── OAuthLoginDialog.xaml │ │ ├── OAuthLoginDialog.xaml.cs │ │ ├── WindowsHelloDisabled.xaml │ │ └── WindowsHelloDisabled.xaml.cs │ ├── Feedback │ │ ├── FeedbackDialog.xaml │ │ ├── FeedbackDialog.xaml.cs │ │ ├── FeedbackDialogViewModel.cs │ │ ├── FeedbackPage.xaml │ │ ├── FeedbackPage.xaml.cs │ │ ├── FeedbackViewModel.cs │ │ ├── Icon.xaml │ │ ├── Icon.xaml.cs │ │ ├── MarkdownPreview.xaml │ │ └── MarkdownPreview.xaml.cs │ ├── FirstUse │ │ ├── FirstUsePage.xaml │ │ ├── FirstUsePage.xaml.cs │ │ ├── ProviderSelectButton.xaml │ │ └── ProviderSelectButton.xaml.cs │ ├── Git │ │ ├── GitInfo.xaml │ │ ├── GitInfo.xaml.cs │ │ ├── GitInfoViewModel.cs │ │ ├── Icon.xaml │ │ └── Icon.xaml.cs │ ├── Guide │ │ ├── GuideHandler.cs │ │ ├── GuideItem.cs │ │ └── GuideSettingMapItem.cs │ ├── HelpDialog.xaml │ ├── HelpDialog.xaml.cs │ ├── Notices │ │ ├── NoticesPage.xaml │ │ ├── NoticesPage.xaml.cs │ │ └── NoticesViewModel.cs │ ├── PasswordCore │ │ ├── FolderEditDialog.xaml │ │ ├── FolderEditDialog.xaml.cs │ │ ├── FolderItem.cs │ │ ├── FolderList.xaml │ │ ├── FolderList.xaml.cs │ │ ├── FolderListViewModel.cs │ │ ├── IconCtl │ │ │ ├── IconControl.xaml │ │ │ ├── IconControl.xaml.cs │ │ │ ├── IconControlViewModel.cs │ │ │ ├── IconSelecter.xaml │ │ │ ├── IconSelecter.xaml.cs │ │ │ ├── IconSource.cs │ │ │ ├── SetPathIcon.xaml │ │ │ └── SetPathIcon.xaml.cs │ │ ├── IconItem.cs │ │ ├── PasswordDetail.xaml │ │ ├── PasswordDetail.xaml.cs │ │ ├── PasswordDetailViewModel.cs │ │ ├── PasswordGenerator.xaml │ │ ├── PasswordGenerator.xaml.cs │ │ ├── PasswordGeneratorViewModel.cs │ │ ├── PasswordItem.cs │ │ ├── PasswordKeyValuePairCustomDialog.xaml │ │ ├── PasswordKeyValuePairCustomDialog.xaml.cs │ │ ├── PasswordKeyValuePairItem.cs │ │ ├── PasswordList.xaml │ │ ├── PasswordList.xaml.cs │ │ ├── PasswordListCommandBar.xaml │ │ ├── PasswordListCommandBar.xaml.cs │ │ ├── PasswordListViewModel.cs │ │ ├── PasswordMoveToDialog.xaml │ │ ├── PasswordMoveToDialog.xaml.cs │ │ └── PasswordMoveToViewModel.cs │ ├── Rating.xaml │ ├── Rating.xaml.cs │ ├── Search │ │ ├── SearchBar.xaml │ │ └── SearchBar.xaml.cs │ ├── Setting │ │ ├── SettingSplitView.xaml │ │ ├── SettingSplitView.xaml.cs │ │ └── SettingViewModel.cs │ ├── Shell │ │ ├── BackSvg.xaml │ │ ├── BackSvg.xaml.cs │ │ ├── Commands.xaml │ │ ├── Commands.xaml.cs │ │ ├── ShellPage.xaml │ │ ├── ShellPage.xaml.cs │ │ ├── Version.xaml │ │ └── Version.xaml.cs │ └── SqliteSync │ │ ├── Crypto │ │ ├── Aes.cs │ │ └── OperationType.cs │ │ ├── Merge.cs │ │ ├── Model │ │ ├── CloudItem.cs │ │ └── CloudType.cs │ │ ├── SqliteFileService.cs │ │ ├── SqliteSyncConstant.cs │ │ ├── SyncHelper │ │ ├── BaseSyncHelper.cs │ │ ├── DavSyncHelper.cs │ │ ├── FileSyncHelper.cs │ │ └── ISyncHelper.cs │ │ ├── View │ │ ├── HistoryDialog.xaml │ │ ├── HistoryDialog.xaml.cs │ │ ├── LoginDialog.xaml │ │ ├── LoginDialog.xaml.cs │ │ ├── SyncDialog.xaml │ │ ├── SyncDialog.xaml.cs │ │ ├── SyncFileHandler.xaml │ │ ├── SyncFileHandler.xaml.cs │ │ ├── Validator.xaml │ │ └── Validator.xaml.cs │ │ └── ViewModel │ │ ├── LoginViewModel.cs │ │ ├── ServiceProvider.cs │ │ ├── SyncHistoryItem.cs │ │ ├── SyncHistoryViewModel.cs │ │ └── SyncViewModel.cs ├── Package.appxmanifest ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── README.md ├── Resources │ ├── Colors.xaml │ └── Styles │ │ ├── Resources.xaml │ │ └── TextBox.xaml └── ServiceProvider.cs ├── Lavcode.sln └── lavcode-node ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── cloudbaserc.json ├── jest.config.js ├── package.json ├── src ├── actions │ ├── auth │ │ ├── _.get.ts │ │ ├── _.head.ts │ │ └── dtos │ │ │ └── get-token.dto.ts │ ├── folder │ │ ├── ^id.delete.ts │ │ ├── ^id.put.ts │ │ ├── _.get.ts │ │ ├── _.post.ts │ │ ├── dtos │ │ │ ├── create-folder.dto.ts │ │ │ ├── get-folder.dto.ts │ │ │ └── update-folder.dto.ts │ │ └── services │ │ │ └── folder.service.ts │ └── password │ │ ├── ^id.delete.ts │ │ ├── ^id.put.ts │ │ ├── _.get.ts │ │ ├── _.post.ts │ │ ├── dtos │ │ ├── craete-password.dto.ts │ │ ├── get-key-value-pair.dto.ts │ │ ├── get-password.dto.ts │ │ ├── update-password.dto.ts │ │ └── upsert-key-value-pair.dto.ts │ │ └── services │ │ └── password.service.ts ├── decorators │ └── open.decorator.ts ├── dtos │ ├── get-icon.dto.ts │ ├── page-list.dto.ts │ ├── page-params.dto.ts │ └── upsert-icon.dto.ts ├── entities │ ├── folder.entity.ts │ ├── icon.entity.ts │ ├── key-value-pair.entity.ts │ └── password-entity.ts ├── enums │ └── icon-type.ts ├── filters │ └── auth.filter.ts ├── index.ts ├── native.ts ├── services │ ├── cbapp.service.ts │ ├── collection.service.ts │ └── dbhelper.service.ts └── startup.ts └── tsconfig.json /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # CS1591: Missing XML comment for publicly visible type or member 4 | dotnet_diagnostic.CS1591.severity = none 5 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'release-v$NEXT_PATCH_VERSION' 2 | tag-template: 'release-v$NEXT_PATCH_VERSION' 3 | categories: 4 | - title: 'Features' 5 | labels: 6 | - 'feature' 7 | - 'enhancement' 8 | - title: 'Bug Fixes' 9 | labels: 10 | - 'fix' 11 | - 'bugfix' 12 | - 'bug' 13 | - title: 'Maintenance' 14 | labels: 15 | - 'chore' 16 | - 'documentation' 17 | change-template: '- $TITLE (#$NUMBER) @$AUTHOR' 18 | template: | 19 | # Changes 20 | 21 | $CHANGES 22 | -------------------------------------------------------------------------------- /.github/workflows/client-feedback.yml: -------------------------------------------------------------------------------- 1 | name: "Client Feedback" 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | 7 | jobs: 8 | create: 9 | if: github.repository == 'hal-wang/Lavcode' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2 14 | with: 15 | node-version: "16" 16 | registry-url: https://registry.npmjs.org/ 17 | - run: node scripts/client-feedback.js ${{ secrets.GITHUB_TOKEN }} ${{ github.event.issue.number }} "${{ github.event.issue.title }}" ${{ github.event.issue.body }} 18 | -------------------------------------------------------------------------------- /.github/workflows/publish-docs.yml: -------------------------------------------------------------------------------- 1 | name: "Publish Docs" 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | publish: 10 | if: github.repository == 'hal-wang/Lavcode' 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: [20.x] 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | 22 | - name: Build 23 | env: 24 | SECRET_KEY: ${{ secrets.NODE_SECRET_KEY }} 25 | ENV_ID: ${{ secrets.NODE_ENV_ID }} 26 | run: | 27 | npm i -g yarn --force 28 | yarn config set registry https://registry.npmjs.org 29 | cd docs 30 | yarn install 31 | yarn build 32 | 33 | - name: Init-Git 34 | run: | 35 | cd docs/.vuepress/dist 36 | git config --global user.name 'hal-wang' 37 | git config --global user.email 'hi@hal.wang' 38 | git init -b gh-pages 39 | git add -A 40 | git commit -m "publish" 41 | 42 | - name: Publish 43 | uses: ad-m/github-push-action@master 44 | with: 45 | directory: docs/.vuepress/dist 46 | repository: hal-wang/Lavcode 47 | force: true 48 | branch: gh-pages 49 | github_token: ${{ secrets.PUSH_REPO }} 50 | -------------------------------------------------------------------------------- /.github/workflows/publish-node.yml: -------------------------------------------------------------------------------- 1 | name: "Publish Node" 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | publish: 10 | if: github.repository == 'hal-wang/Lavcode' 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: [20.x] 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | - name: Setup ENV 22 | env: 23 | SECRET_KEY: ${{ secrets.NODE_SECRET_KEY }} 24 | ENV_ID: ${{ secrets.NODE_ENV_ID }} 25 | run: | 26 | cd src/lavcode-node 27 | npm install 28 | echo -e "SECRET_KEY=$SECRET_KEY\nENV_ID=$ENV_ID" > ./.env.local 29 | - name: Publish 30 | env: 31 | TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }} 32 | TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }} 33 | run: | 34 | cd src/lavcode-node 35 | npx tcb login --apiKeyId $TENCENT_SECRET_ID --apiKey $TENCENT_SECRET_KEY 36 | npx tcb framework deploy --mode local 37 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - main 8 | # pull_request event is required only for autolabeler 9 | pull_request: 10 | # Only following types are handled by the action, but one can default to all as well 11 | types: [opened, reopened, synchronize] 12 | 13 | jobs: 14 | update_release_draft: 15 | runs-on: ubuntu-latest 16 | steps: 17 | # Drafts your next Release notes as Pull Requests are merged into "master" 18 | - uses: release-drafter/release-drafter@v5 19 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 20 | # with: 21 | # config-name: my-config.yml 22 | # disable-autolabeler: true 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Hal Wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | .temp 5 | .cache 6 | 7 | # local env files 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw* 24 | 25 | package-lock.json -------------------------------------------------------------------------------- /docs/.vuepress/config.ts: -------------------------------------------------------------------------------- 1 | import { defaultTheme, defineUserConfig } from "vuepress"; 2 | 3 | const usagePages = [ 4 | { 5 | text: "新手指南", 6 | children: ["start.md", "password.md", "problem.md"], 7 | }, 8 | { 9 | text: "基础", 10 | children: ["safety.md", "sync.md", "window.md", "svgicon.md"], 11 | }, 12 | { 13 | text: "进阶", 14 | children: ["command.md", "contribute.md", "api.md"], 15 | }, 16 | ]; 17 | 18 | const navbarUsagePages = usagePages.map((item) => 19 | Object.assign({}, item, { 20 | children: item.children.map((item) => `/usage/${item}`), 21 | }) 22 | ); 23 | 24 | export default defineUserConfig({ 25 | lang: "zh-CN", 26 | title: "Lavcode", 27 | description: "Lavcode 开源密码管理", 28 | head: [["link", { rel: "icon", href: "/logo.png" }]], 29 | base: "/", 30 | theme: defaultTheme({ 31 | repo: "https://github.com/hal-wang/Lavcode", 32 | docsRepo: "hal-wang/Lavcode", 33 | docsBranch: "main", 34 | docsDir: "docs", 35 | editLinkPattern: ":repo/edit/:branch/docs/:path", 36 | editLink: true, 37 | editLinkText: "编辑此页", 38 | logo: "/logo.png", 39 | home: "/index.md", 40 | sidebarDepth: 2, 41 | backToHome: "返回主页", 42 | notFound: ["你访问的页面不存在"], 43 | navbar: [ 44 | { text: "首页", link: "/index.md" }, 45 | ...navbarUsagePages, 46 | { 47 | text: "下载", 48 | ariaLabel: "下载", 49 | children: [ 50 | { 51 | text: "Windows 10/11", 52 | link: "https://www.microsoft.com/store/apps/9N3N7R34ZJDC", 53 | }, 54 | ], 55 | }, 56 | { text: "捐赠", link: "/donate.md" }, 57 | ], 58 | sidebar: { 59 | "/usage/": usagePages, 60 | "/pp/": ["en.md", "zh.md"], 61 | }, 62 | }), 63 | }); 64 | -------------------------------------------------------------------------------- /docs/.vuepress/public/CNAME: -------------------------------------------------------------------------------- 1 | lavcode.hal.wang -------------------------------------------------------------------------------- /docs/.vuepress/public/baidu_verify_code-VFp5HmU9au.html: -------------------------------------------------------------------------------- 1 | 8044f3c476645dda3e44c5dd20844edb -------------------------------------------------------------------------------- /docs/.vuepress/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/logo.png -------------------------------------------------------------------------------- /docs/.vuepress/public/logo_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/logo_bw.png -------------------------------------------------------------------------------- /docs/.vuepress/public/logo_wb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/logo_wb.png -------------------------------------------------------------------------------- /docs/.vuepress/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Lavcode", 3 | "short_name": "Lavcode", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "background_color": "#ffffff", 7 | "description": "Lavcode 开源密码管理", 8 | "theme_color": "blue", 9 | "icons": [ 10 | { 11 | "src": "/logo.png", 12 | "sizes": "144x144", 13 | "type": "image/png" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /docs/.vuepress/public/screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/screenshots/1.png -------------------------------------------------------------------------------- /docs/.vuepress/public/screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/screenshots/2.png -------------------------------------------------------------------------------- /docs/.vuepress/public/screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/screenshots/3.png -------------------------------------------------------------------------------- /docs/.vuepress/public/screenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/.vuepress/public/screenshots/4.png -------------------------------------------------------------------------------- /docs/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | // 默认值 2 | $accentColor = #3eaf7c 3 | $textColor = #2c3e50 4 | $borderColor = #eaecef 5 | $codeBgColor = #282c34 6 | $badgeTipColor = #42b983 7 | $badgeWarningColor = darken(#ffe564, 35%) 8 | $badgeErrorColor = #DA5961 -------------------------------------------------------------------------------- /docs/donate.md: -------------------------------------------------------------------------------- 1 | # 捐赠 2 | 3 | ## 赞助 Lavcode 的开发 4 | 5 | Lavcode 采用 MIT 许可的开源项目,使用完全免费。 但随着软件的改进,也需要有相应的资金支持才能持续项目的维护的开发。你可以通过下列的方法来赞助 Lavcode 的开发。 6 | 7 | 11 | 12 | 36 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /logo.png 4 | heroText: Lavcode 密码管理 5 | tagline: 安全、免费、丰富、开源的密码管理器 6 | actions: 7 | - text: 快速开始 8 | link: /usage/start 9 | type: primary 10 | - text: 下载 11 | type: secondary 12 | link: https://www.microsoft.com/store/apps/9N3N7R34ZJDC 13 | - text: GitHub 14 | type: secondary 15 | link: https://github.com/hal-wang/Lavcode 16 | - text: Gitee 17 | type: secondary 18 | link: https://gitee.com/hal-wang/Lavcode 19 | features: 20 | - title: 免费开源 21 | details: 完全免费开源,代码公开透明,无后台,无窃取。安全管理存储密码。 22 | - title: 云同步 23 | details: 支持 GitHub/Gitee 存储,也支持自定义第三方 WebDav 网盘同步,加密同步文件,安全可靠。 24 | - title: 功能丰富 25 | details: 文件夹管理;复杂密码生成器;字体、图片、svg 图标;多窗口运行......给你想要的自定义。 26 | footer: MIT Licensed | Copyright © Hal Wang 27 | --- 28 | 29 |

30 | 31 | 32 | repo size 33 | GitHub Issues 34 | 35 | 36 | 37 |

38 | 39 | 44 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lavcode", 3 | "version": "1.1.3", 4 | "description": "Lavcode 官方网站", 5 | "scripts": { 6 | "start": "vuepress dev .", 7 | "dev": "npm start", 8 | "build": "vuepress build ." 9 | }, 10 | "author": "hal-wang", 11 | "license": "MIT", 12 | "dependencies": { 13 | "vuepress": "2.0.0-beta.61", 14 | "vuepress-vite": "2.0.0-beta.61" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/pp/en.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Privacy Policy" 3 | --- 4 | 5 | ## What Information do We Collect ? 6 | 7 | We will NOT collect any personal information from you, including your in-App data or your shared information in the App. 8 | 9 | ## What Information do Third-Party Collect ? 10 | 11 | Any thrid party libraies (e.g. Microsoft Azure App Insight) may collect telemetry diagnosis data to be able to find problems in code. But any of the libraries would not collect our personal information. 12 | 13 | If you choose to store data in `GitHub`/`Gitee`, you need to ensure the security of relevant accounts and depositories. 14 | 15 | ## How do you manage information 16 | 17 | This is an open source software without any profit nature and does not provide guarantee services. Please keep your personal data (including timely backup, synchronization, etc.). 18 | 19 | If you accidentally cause data loss (including improper operation, software error, etc.) in the process of use, the developer is obliged to provide technical assistance within the scope of its ability, but does not bear any legal responsibility or make any compensation. 20 | 21 | ## Data security 22 | 23 | The data backed up on the cloud disk or the data backed up locally have been encrypted by aes256 and can hardly be brutally cracked at this stage. Please keep your encryption password safely and try to use complex passwords for encryption. 24 | 25 | Local temporary data is not encrypted. Do not use Lavcode on other people's devices (or public devices). If you must use it, please back up the data after use, and reset or uninstall the Lavcode. 26 | 27 | ## Changes to Our Privacy Policy 28 | 29 | If we decide to change our privacy policy, we will post those changes on this page, and update the privacy policy modification data below. 30 | 31 | _This policy was last modified on 2021/12/13_ 32 | 33 | ## Contacting Us 34 | 35 | If there are any questions regarding this privacy policy you may contact us by email: 36 | -------------------------------------------------------------------------------- /docs/pp/zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lavcode 隐私政策 3 | --- 4 | 5 | ## 我们收集的信息 6 | 7 | 可能会在用户同意的情况下收集应用的错误日志,用于改进软件。但不会收集任何用户密码信息、同步信息。 8 | 9 | ## 第三方收集的信息 10 | 11 | 第三方(如微软等)可能会收集软件错误信息、软件使用统计等,但是不会收集用户个人信息。 12 | 13 | 如果你选择将数据存储在 `GitHub`/`Gitee`, 你需要自己保证相关账号和仓库的安全性。 14 | 15 | ## 您如何管理信息 16 | 17 | 此软件属于开源软件,无任何盈利性质,不提供保障服务,请自行保管好个人数据(包括及时备份、同步等)。 18 | 19 | 如果您在使用过程中意外造成数据丢失(包括操作不当、软件错误等),开发者有义务在能力范围之内提供技术帮助,但不负任何法律责任,也无需进行任何赔偿。 20 | 21 | ## 数据安全 22 | 23 | 备份在网盘的数据,或者备份的文件,已经经过 AES256 加密,现阶段几乎无法暴力破解,请保管好自己的加密密码,尽量使用复杂密码进行加密。 24 | 25 | 本地临时数据未经加密,请勿在他人的设备(或公共设备)上使用,如必须使用,请在使用完毕后备份数据,并对软件进行重置或卸载。 26 | 27 | ## 隐私政策变动 28 | 29 | 如果我们要改变隐私政策,会在这个页面提前通知。 30 | 31 | _此隐私政策最近修改时间:2021/12/13。_ 32 | 33 | ## 联系我们 34 | 35 | 如果对此隐私政策有任何疑问,请联系 。 36 | -------------------------------------------------------------------------------- /docs/usage/api/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/api/add.png -------------------------------------------------------------------------------- /docs/usage/api/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/api/edit.png -------------------------------------------------------------------------------- /docs/usage/api/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/api/login.png -------------------------------------------------------------------------------- /docs/usage/api/mng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/api/mng.png -------------------------------------------------------------------------------- /docs/usage/api/secrets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/api/secrets.png -------------------------------------------------------------------------------- /docs/usage/api/url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/api/url.png -------------------------------------------------------------------------------- /docs/usage/command.md: -------------------------------------------------------------------------------- 1 | # 用命令打开 2 | 3 | 可用命令快速打开 Lavcode,格式为 `lavcode` 或 `lavcode + 存储方式` 4 | 5 | - 快速打开 6 | - `lavcode` 7 | - GitHub 8 | - `lavcode git` 9 | - `lavcode github` 10 | - Gitee 11 | - `lavcode gitee` 12 | - `lavcode 码云` 13 | - 本地 14 | - `lavcode local` 15 | - `lavcode sqlite` 16 | - API 17 | - `lavcode api` 18 | - `lavcode net` 19 | -------------------------------------------------------------------------------- /docs/usage/contribute.md: -------------------------------------------------------------------------------- 1 | # 贡献 2 | 3 | 欢迎任何人对本项目贡献,让 Lavcode 持续改进 4 | 5 | - 有好的想法请在这里提:[Discussions](https://github.com/hal-wang/Lavcode/discussions) 6 | - 软件错误请在这里提:[Issues](https://github.com/hal-wang/Lavcode/issues) 7 | - 代码改进欢迎提交 [PR](https://github.com/hal-wang/Lavcode/pulls) 8 | 9 | ## 贡献列表 10 | 11 | 12 | 13 | 14 | 15 | _列表自动更新_ 16 | -------------------------------------------------------------------------------- /docs/usage/password.md: -------------------------------------------------------------------------------- 1 | # 密码管理 2 | 3 | ## 文件夹 4 | 5 | 文件夹用于分类管理密码,如 工作、学习、家人、社交 等分类 6 | 7 | 先创建文件夹,在文件夹中再创建密码 8 | 9 | ## 密码数量 10 | 11 | 理论上支持无限多的文件夹,每个文件夹支持无限多的密码,每条密码支持无限多的键值内容。 12 | 13 | ::: tip 14 | 如果你的密码数以千计(正常人都没有吧),可以分为多个密码文件存放。 15 | ::: 16 | 17 | ## 排序 18 | 19 | 文件夹、密码都可拖拽进行排序。把最经常用的密码拖到前面来吧! 20 | 21 | ## 其他操作 22 | 23 | 可将密码单个或批量,移动至另一个文件夹。 24 | 25 | ## 图标 26 | 27 | 每个文件或密码都支持添加图标,可帮助你快速找到目标。 28 | 29 | 图标不仅支持字体,还支持图片,更支持强大丰富的 svg 路径图。 30 | 31 | [如何使用 svg 图标?](./svgicon) 32 | 33 | :::tip 34 | 建议使用内置字体或 svg 图,在 [iconfont](https://www.iconfont.cn/collections) 有海量免费图标。 35 | ::: 36 | 37 | ::: danger 38 | 非常不建议使用图片,图片会使密码文件变得很臃肿,影响同步速度和操作速度。 39 | ::: 40 | 41 | ## 复杂密码生成器 42 | 43 | 如果你的记忆不太强,应该是每个网站密码都相同,但如果有个网站的密码泄露,别人将可以登录你其他账号。 44 | 45 | 因此安全的做法是尽可能有多个不同的密码。防止相同密码泄露。 46 | 47 | Lavcode 即可以帮你记密码,又可以帮你“创造”密码。 48 | 49 | 在新建密码记录时,可以生成复杂密码,再使用此密码注册网站。安全又省心。 50 | 51 | ::: tip 52 | 生成密码时可以配置大小写字母、数字、特殊字符 53 | ::: 54 | -------------------------------------------------------------------------------- /docs/usage/problem.md: -------------------------------------------------------------------------------- 1 | # 遇到问题 2 | 3 | 如果是一般性问题,请在这里寻找答案或提问:[Discussions](https://github.com/hal-wang/Lavcode/discussions) 4 | 5 | 如果软件出现 BUG,请在这里寻找答案或提问:[Issues](https://github.com/hal-wang/Lavcode/issues) 6 | 7 | 如果是代码有问题,并且你能够修改,欢迎提交 [PR](https://github.com/hal-wang/Lavcode/pulls) 8 | -------------------------------------------------------------------------------- /docs/usage/safety.md: -------------------------------------------------------------------------------- 1 | # 安全性 2 | 3 | 对于一款密码管理软件来说,安全性是首要的。使用`Lavcode`,你管理的密码不用担心被他人获取,你的密码也不会丢失。 4 | 5 | ## 开源安全 6 | 7 | Lavcode 是开源软件,所有代码公开透明。因此你无需担心密码有被窃取的危险。 8 | 9 | ::: tip 10 | 源码请访问 [GitHub](https://github.com/hal-wang/Lavcode) 或 [Gitee](https://gitee.com/hal-wang/Lavcode) 11 | ::: 12 | 13 | ## 备份安全 14 | 15 | Lavcode 支持以下备份方式: 16 | 17 | 1. GitHub/Gitee 存储 18 | 2. WebDav 云同步 19 | 3. 文件同步 20 | 21 | 详情看下面[备份](#备份)部分。 22 | 23 | ## 网络安全 24 | 25 | 虽然 Lavcode 有联网权限,但只用于以下几处: 26 | 27 | 1. 获取 GitHub 相关的源码、评论、通知信息等时 28 | 1. 使用 GitHub/Gitee 存储时 29 | 1. WebDav 同步时(仅与第三方网盘通讯,使用哪个网盘由你自定义) 30 | 1. 从应用商店获取应用信息时,如检查更新、评论等 31 | 32 | ::: tip 33 | 如果你懂网络监听技术,会发现`Lavcode`除以上几条外,完全无任何网络访问行为。 34 | ::: 35 | -------------------------------------------------------------------------------- /docs/usage/start.md: -------------------------------------------------------------------------------- 1 | # 快速开始 2 | 3 | ## 下载安装 4 | 5 | `Lavcode` 发布在 `Win10/11` 应用商店 Microsoft Store 6 | 7 | - 你可以在应用商店内搜索 `Lavcode` 并下载安装 8 | - 也可以点击链接跳转: 9 | 10 | ## 存储位置 11 | 12 | 首次打开软件,会让你选择存储位置,根据描述选择即可 13 | 14 | ![存储位置](./start/storage.png) 15 | 16 | ## 引导 17 | 18 | 首次打开软件,会有使用教程 19 | 20 | 跟着教程走一遍一般就会使用了 21 | 22 | ## 界面 23 | 24 | 主题色跟随系统,美观多彩的密码管理有木有!!! 25 | 26 | 上几张截图 27 | 28 | ![截图1](/screenshots/1.png) 29 | ![截图2](/screenshots/2.png) 30 | ![截图3](/screenshots/3.png) 31 | ![截图4](/screenshots/4.png) 32 | -------------------------------------------------------------------------------- /docs/usage/start/storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/start/storage.png -------------------------------------------------------------------------------- /docs/usage/svgicon.md: -------------------------------------------------------------------------------- 1 | # SVG 图标 2 | 3 | 目前支持 3 种图标: 4 | 5 | 1. 图片:不建议使用,由于图片占用空间比较大,会严重影响同步速度和加载速度 6 | 2. 字体图标:可满足一般需求,选择范围有限 7 | 3. 路径图:推荐使用。选择范围广,图标极其丰富 8 | 9 | 1 和 2 都很简单,选择就行。 10 | 11 | 这里介绍如何使用路径图。 12 | 13 | ## 找图标 14 | 15 | 推荐网站 [iconfont.cn](https://www.iconfont.cn/collections) 16 | 17 | ![iconfont](./svgicon/1.png) 18 | 19 | 可浏览选择,也可在右上角处搜索,比如搜索“文件夹”可显示如下图片 20 | 21 | ![搜索“文件夹”](./svgicon/2.png) 22 | 23 | ## 复制内容 24 | 25 | 找到想要的图标后,鼠标移上去,点“下载” 26 | 27 | ![下载”](./svgicon/3.png) 28 | 29 | 再点击“复制” 30 | 31 | ![复制](./svgicon/4.png) 32 | 33 | ## 软件内使用 34 | 35 | 在设置路径图的弹窗中,直接粘贴到文本框中即可 36 | 37 | ![复制](./svgicon/5.png) 38 | 39 | 再点击确定就设置完成了 40 | 41 | ![复制](./svgicon/6.png) 42 | -------------------------------------------------------------------------------- /docs/usage/svgicon/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/svgicon/1.png -------------------------------------------------------------------------------- /docs/usage/svgicon/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/svgicon/2.png -------------------------------------------------------------------------------- /docs/usage/svgicon/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/svgicon/3.png -------------------------------------------------------------------------------- /docs/usage/svgicon/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/svgicon/4.png -------------------------------------------------------------------------------- /docs/usage/svgicon/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/svgicon/5.png -------------------------------------------------------------------------------- /docs/usage/svgicon/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/docs/usage/svgicon/6.png -------------------------------------------------------------------------------- /docs/usage/sync.md: -------------------------------------------------------------------------------- 1 | # 备份 2 | 3 | ## GitHub/Gitee 存储 4 | 5 | 使用 `OAuth2` 登录,首次使用 Lavcode 会为你创建一个名为 `LavcodeStorage` 的仓库 6 | 7 | ## WebDav 云同步 8 | 9 | WebDAV 的 [百度百科](https://baike.baidu.com/item/WebDAV) 介绍 10 | 11 | 可自由选择第三方支持 WebDav 的网盘,同步文件经过你的密码加密,即使把文件发给别人,别人也看不到内容。 12 | 13 | ### 可使用什么网盘? 14 | 15 | 只要是支持 WebDAV 的网盘都支持同步,国内推荐坚果云 16 | 17 | ### 如何获取账号? 18 | 19 | 以坚果云为例,在 [坚果云官网](https://www.jianguoyun.com/) 注册账号即可 20 | 21 | ### 使用费用 22 | 23 | 本软件完全免费无广告,无附加收费产品。可能某些网盘会收费,但与本软件无关 24 | 25 | ## 文件同步 26 | 27 | 不仅可以同步到云,可以把本地文件当作同步介质。导出文件后放在硬盘、U 盘,可随时同步,可随时查看、编辑。 28 | 29 | 当然,文件也是经过你输入的密码加密的,即使文件被别人弄走,也看不了。 30 | 31 | 文件不仅支持更新同步,还能直接打开查看和修改。(可以把一个文件当成一个密码箱。) 32 | 33 | ::: tip 进阶操作 34 | 你可以把备份文件放到 OneDrive 或其他同步文件夹,每次编辑保存后会自动云同步。 35 | 36 | 此方法类似于 OneNote 。 37 | ::: 38 | 39 | ## 加密方式 40 | 41 | WebDav 云同步和文件同步,备份文件一律使用`AES256`加密。 42 | 43 | ::: tip 44 | `AES256`也叫`高级加密标准`,目前无法破解。 45 | ::: 46 | 47 | ## 与云端(或文件)合并 48 | 49 | 同步方式不止是傻傻的覆盖,同时也支持智能合并。 50 | 51 | 你再也不用担心几台电脑,同步来同步去把内容搞丢了。 52 | 53 | 只能合并大体按以下逻辑进行: 54 | 55 | 1. 删除曾经删除过的记录。不管是在备份介质中删除,还是在本地被删除,合并后该文件夹或密码都不会存在。 56 | 2. 找到二者都存在的文件夹或密码,根据最后编辑日期,选择较晚的作为最终结果。 57 | 3. 找到二者不同时存在的文件夹或密码,添加至最终结果。 58 | 4. 合并后,本地和云端(或文件)都会更新,本地先前的内容会备份至“历史记录”,可随时导出或删除。 59 | 60 | ## 云端(或文件)覆盖本地 61 | 62 | 以云端(或文件)为准,把云端(或文件)内容全部下载本地,不保留原先本地内容。 63 | 64 | 此方法适合本地无数据,或本地数据不重要的情况。 65 | 66 | ## 本地覆盖云端(或文件) 67 | 68 | 以本地为准,把本地内容全部上传云端(或文件),不保留原先云端(或文件)内容。 69 | 70 | 此方法适合未备份至云端(或文件),或云端(或文件)数据不重要的情况。 71 | 72 | ## 同步密码设置 73 | 74 | 同步密码用于加密备份文件 75 | 76 | - 如果是云同步,则加密云端文件 77 | - 如果是文件同步,则加密同步文件 78 | 79 | 密码设置后会缓存在软件中。同步时,或打开同步文件,如果缓存密码正确则无需再次输入密码。缓存密码可以随时修改。 80 | 81 | ## 历史记录 82 | 83 | 仅记录本地,不记录云端和同步文件。 84 | 85 | 即如果同步有可能改变本地数据,就会将本地原先的数据加入历史记录。 86 | 87 | 以下几种情况会产生历史记录: 88 | 89 | 1. 云端(或文件)覆盖本地。 90 | 2. 与云端(或文件)合并 91 | 92 | 历史记录可任意导出或删除。导出的历史记录,是一个同步文件,可随时还原。 93 | -------------------------------------------------------------------------------- /docs/usage/window.md: -------------------------------------------------------------------------------- 1 | # 多窗口 2 | 3 | 只能打开一个密码文件怎么能忍?Lavcode 支持同时打开多个文件,即一个文件对应一个应用窗口。 4 | 5 | ## 多窗口联动 6 | 7 | 打开多个窗口后,还可以有更多骚操作 8 | 9 | 比如:有多个密码文件想复制密码怎么办?或把你男(女)朋友的密码复制过来! 10 | 11 | 简单!直接拖拽就能复制。在多选状态下,还能批量拖拽。 12 | 13 | 把密码从一个密码文件复制到另一个密码文件,或者从密码文件复制到软件,或从软件复制到密码文件,真是如此简单! 14 | 15 | ::: tip 16 | 当然,文件打开的前提是你有正确的密码 17 | ::: 18 | -------------------------------------------------------------------------------- /scripts/client-feedback.js: -------------------------------------------------------------------------------- 1 | const https = require("https"); 2 | 3 | const args = process.argv; 4 | 5 | const token = args[2]; 6 | const issueNumber = args[3]; 7 | const title = args[4]; 8 | const body = args[5]; 9 | 10 | (async () => { 11 | if (!title || !body) return; 12 | if (title != "From client, DO NOT EDIT!") return; 13 | const bodyObj = JSON.parse(Buffer.from(body, "base64").toString("utf-8")); 14 | if (!bodyObj) return; 15 | console.log("bodyObj", bodyObj); 16 | const req = https.request( 17 | { 18 | hostname: "api.github.com", 19 | port: 443, 20 | path: `/repos/hal-wang/Lavcode/issues/${issueNumber}`, 21 | method: "PATCH", 22 | headers: { 23 | Authorization: `Bearer ${token}`, 24 | Accept: "application/vnd.github+json", 25 | "user-agent": 26 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.42", 27 | }, 28 | }, 29 | (res) => { 30 | let chunks = Buffer.from([]); 31 | let chunksLength = chunks.length; 32 | res.on("data", (data) => { 33 | chunks = Buffer.concat([chunks, data], chunksLength + data.length); 34 | chunksLength = chunks.length; 35 | }); 36 | res.on("end", () => { 37 | console.log("end", chunks.toString("utf-8")); 38 | }); 39 | 40 | console.log("statusCode", res.statusCode); 41 | } 42 | ); 43 | req.on("error", (err) => { 44 | console.log("err", err); 45 | }); 46 | req.write( 47 | JSON.stringify({ 48 | title: bodyObj.title, 49 | body: bodyObj.body, 50 | labels: [ 51 | "client feedback", 52 | `platform ${bodyObj.platform}`, 53 | `version ${bodyObj.version}`, 54 | `provider ${bodyObj.provider}`, 55 | ], 56 | assignees: ["hal-wang"], 57 | }) 58 | ); 59 | req.end(); 60 | })(); 61 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Controllers/AuthController.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Asp.Services; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Text; 6 | 7 | namespace Lavcode.Asp.Controllers 8 | { 9 | [ApiController] 10 | [Route("auth")] 11 | public class AuthController : ControllerBase 12 | { 13 | private readonly AuthTokenService _authTokenService; 14 | private readonly IConfiguration _configuration; 15 | public AuthController(AuthTokenService authTokenService, IConfiguration configuration) 16 | { 17 | _authTokenService = authTokenService; 18 | _configuration = configuration; 19 | } 20 | 21 | /// 22 | /// Get login token 23 | /// 24 | /// Lavcode password 25 | /// 26 | [HttpGet] 27 | public IActionResult GetToken([FromQuery, Required] string password) 28 | { 29 | var secretKey = _configuration["SecretKey"]; 30 | try 31 | { 32 | var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(password)); 33 | if (base64 != secretKey) 34 | { 35 | return Unauthorized("密码错误"); 36 | } 37 | } 38 | catch (FormatException) 39 | { 40 | return BadRequest("password must be base64 encoded"); 41 | } 42 | 43 | var token = _authTokenService.CreateJwtToken(); 44 | return this.Ok(new 45 | { 46 | token 47 | }); 48 | } 49 | 50 | /// 51 | /// Verify token 52 | /// 53 | /// 54 | [HttpHead] 55 | [Authorize] 56 | public IActionResult VerifyToken() 57 | { 58 | return this.NoContent(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build 9 | WORKDIR /src 10 | COPY ["Lavcode.Asp/Lavcode.Asp.csproj", "Lavcode.Asp/"] 11 | RUN dotnet restore "Lavcode.Asp/Lavcode.Asp.csproj" 12 | COPY . . 13 | WORKDIR "/src/Lavcode.Asp" 14 | RUN dotnet build "Lavcode.Asp.csproj" -c Release -o /app/build 15 | 16 | FROM build AS publish 17 | RUN dotnet publish "Lavcode.Asp.csproj" -c Release -o /app/publish /p:UseAppHost=false 18 | 19 | FROM base AS final 20 | WORKDIR /app 21 | COPY --from=publish /app/publish . 22 | ENTRYPOINT ["dotnet", "Lavcode.Asp.dll"] -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dtos/CreateFolderDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Lavcode.Asp.Dtos 4 | { 5 | public class CreateFolderDto 6 | { 7 | [Required] 8 | public string Name { get; set; } = null!; 9 | 10 | [Required] 11 | public UpsertIconDto Icon { get; set; } = null!; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dtos/CreatePasswordDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Lavcode.Asp.Dtos 4 | { 5 | public class CreatePasswordDto 6 | { 7 | [Required] 8 | public string FolderId { get; set; } = null!; 9 | 10 | public string? Title { get; set; } 11 | public string? Value { get; set; } 12 | public string? Remark { get; set; } 13 | 14 | [Required] 15 | public UpsertIconDto Icon { get; set; } = null!; 16 | 17 | [Required] 18 | public UpsertKeyValuePairDto[] KeyValuePairs { get; set; } = null!; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dtos/UpdateFolderDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Lavcode.Asp.Dtos 4 | { 5 | public class UpdateFolderDto 6 | { 7 | [Required] 8 | public string Name { get; set; } = null!; 9 | 10 | [Required] 11 | public int Order { get; set; } 12 | 13 | /// 14 | /// 空则不修改图标 15 | /// 16 | public UpsertIconDto? Icon { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dtos/UpdatePasswordDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Lavcode.Asp.Dtos 4 | { 5 | public class UpdatePasswordDto 6 | { 7 | [Required] 8 | public string FolderId { get; set; } = null!; 9 | 10 | public string? Title { get; set; } 11 | public string? Value { get; set; } 12 | public string? Remark { get; set; } 13 | 14 | [Required] 15 | public int Order { get; set; } 16 | 17 | public UpsertIconDto? Icon { get; set; } = null!; 18 | public UpsertKeyValuePairDto[]? KeyValuePairs { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dtos/UpsertIconDto.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace Lavcode.Asp.Dtos 5 | { 6 | public class UpsertIconDto 7 | { 8 | [Required] 9 | public IconType IconType { get; set; } 10 | 11 | [Required] 12 | public string Value { get; set; } = null!; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Dtos/UpsertKeyValuePairDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Lavcode.Asp.Dtos 4 | { 5 | public class UpsertKeyValuePairDto 6 | { 7 | [Required] 8 | public string Key { get; set; } = null!; 9 | [Required] 10 | public string Value { get; set; } = null!; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Entities/DatabaseContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using static System.Net.Mime.MediaTypeNames; 3 | 4 | namespace Lavcode.Asp.Entities 5 | { 6 | public class DatabaseContext : DbContext 7 | { 8 | public DatabaseContext() 9 | { 10 | } 11 | 12 | public DatabaseContext(DbContextOptions options) 13 | : base(options) 14 | { 15 | } 16 | 17 | public DbSet Folders { get; set; } = null!; 18 | public DbSet Passwords { get; set; } = null!; 19 | public DbSet Icons { get; set; } = null!; 20 | public DbSet KeyValuePairs { get; set; } = null!; 21 | 22 | protected override void OnModelCreating(ModelBuilder modelBuilder) 23 | { 24 | modelBuilder.Entity(entity => 25 | { 26 | entity.HasOne(d => d.Icon) 27 | .WithOne(p => p.Folder) 28 | .HasForeignKey(d => d.Id) 29 | .OnDelete(DeleteBehavior.ClientSetNull) 30 | .HasConstraintName("FK_Folder_Icon"); 31 | }); 32 | modelBuilder.Entity(entity => 33 | { 34 | entity.HasOne(d => d.Icon) 35 | .WithOne(p => p.Password) 36 | .HasForeignKey(d => d.Id) 37 | .OnDelete(DeleteBehavior.ClientSetNull) 38 | .HasConstraintName("FK_Password_Icon"); 39 | }); 40 | base.OnModelCreating(modelBuilder); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Entities/FolderEntity.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace Lavcode.Asp.Entities 5 | { 6 | [Table("Folder")] 7 | public class FolderEntity 8 | { 9 | public FolderEntity() 10 | { 11 | Passwords = new HashSet(); 12 | } 13 | 14 | [Key] 15 | public string Id { get; set; } = null!; 16 | 17 | [MaxLength(100)] 18 | public string Name { get; set; } = null!; 19 | 20 | public int Order { get; set; } 21 | 22 | public long UpdatedAt { get; set; } 23 | 24 | [ForeignKey("Id")] 25 | public virtual IconEntity Icon { get; set; } = null!; 26 | public virtual ICollection Passwords { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Entities/IconEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | 5 | namespace Lavcode.Asp.Entities 6 | { 7 | [Table("Icon")] 8 | public class IconEntity 9 | { 10 | [Key] 11 | public string Id { get; set; } = null!; 12 | 13 | /// 14 | /// 图标类型 15 | /// 16 | public IconType IconType { get; set; } 17 | 18 | /// 19 | /// 字体:1字符+字体名称 20 | /// 图片:Base64字符串 21 | /// 22 | [MaxLength(1024 * 1024 * 10)] 23 | public string Value { get; set; } = null!; 24 | 25 | public virtual FolderEntity? Folder { get; set; } 26 | public virtual PasswordEntity? Password { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Entities/KeyValuePairEntity.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace Lavcode.Asp.Entities 5 | { 6 | [Table("KeyValuePair")] 7 | public class KeyValuePairEntity 8 | { 9 | [Key] 10 | public string Id { get; set; } = null!; 11 | 12 | public string PasswordId { get; set; } = null!; 13 | public string Key { get; set; } = null!; 14 | public string Value { get; set; } = null!; 15 | 16 | public virtual PasswordEntity Password { get; set; } = null!; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Entities/PasswordEntity.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace Lavcode.Asp.Entities 5 | { 6 | [Table("Password")] 7 | public class PasswordEntity 8 | { 9 | public PasswordEntity() 10 | { 11 | KeyValuePairs = new HashSet(); 12 | } 13 | 14 | [Key] 15 | public string Id { get; set; } = null!; 16 | public string FolderId { get; set; } = null!; 17 | 18 | [MaxLength(100)] 19 | public string? Title { get; set; } 20 | 21 | /// 22 | /// 密码 23 | /// 24 | [MaxLength(100)] 25 | public string? Value { get; set; } 26 | 27 | [MaxLength(500)] 28 | public string? Remark { get; set; } 29 | 30 | public int Order { get; set; } 31 | 32 | public long UpdatedAt { get; set; } 33 | 34 | [ForeignKey("Id")] 35 | public virtual IconEntity Icon { get; set; } = null!; 36 | public virtual FolderEntity Folder { get; set; } = null!; 37 | public virtual ICollection KeyValuePairs { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Filters/ErrorFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace Lavcode.Asp.Filters 5 | { 6 | public class ErrorFilter : IActionFilter 7 | { 8 | public void OnActionExecuted(ActionExecutedContext context) 9 | { 10 | var result = context.Result; 11 | if (result is ObjectResult objectResult && objectResult.Value != null) 12 | { 13 | var value = objectResult.Value; 14 | if (value.GetType() == typeof(string)) 15 | { 16 | objectResult.Value = new 17 | { 18 | message = value 19 | }; 20 | } 21 | } 22 | } 23 | 24 | public void OnActionExecuting(ActionExecutingContext context) 25 | { 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Filters/ExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace Lavcode.Asp.Filters 5 | { 6 | public class ExceptionFilter : IExceptionFilter 7 | { 8 | public void OnException(ExceptionContext context) 9 | { 10 | if (context.Exception is not HttpRequestException exception) 11 | { 12 | return; 13 | } 14 | 15 | context.ExceptionHandled = true; 16 | 17 | context.HttpContext.Response.Headers.TryAdd("source-exception", exception.GetType().ToString()); 18 | var message = context.Exception.Message; 19 | var objectResult = new ObjectResult(new 20 | { 21 | message = string.IsNullOrEmpty(message) ? "error" : message, 22 | }) 23 | { 24 | StatusCode = exception.StatusCode == null ? 500 : (int)exception.StatusCode, 25 | }; 26 | context.Result = objectResult; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Filters/ValidateFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace Lavcode.Asp.Filters 5 | { 6 | public class ValidateFilter : IActionFilter 7 | { 8 | public void OnActionExecuted(ActionExecutedContext context) 9 | { 10 | 11 | } 12 | 13 | public void OnActionExecuting(ActionExecutingContext context) 14 | { 15 | var modelState = context.ModelState; 16 | if (modelState.IsValid) 17 | { 18 | return; 19 | } 20 | 21 | var state = modelState 22 | .Select(item => item.Value) 23 | .FirstOrDefault(item => item != null && item.Errors.Count > 0); 24 | if (state == default) 25 | { 26 | return; 27 | } 28 | 29 | context.Result = new BadRequestObjectResult(new 30 | { 31 | message = state.Errors[0].ErrorMessage 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Lavcode.Asp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 1b36d038-c844-4ef9-a8e0-df2c3ab3a009 8 | Linux 9 | .\doc.xml 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/Program.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Asp/Program.cs -------------------------------------------------------------------------------- /src/Lavcode.Asp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Lavcode.Asp": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "swagger", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | }, 10 | "dotnetRunMessages": true, 11 | "applicationUrl": "https://localhost:7265;http://localhost:5265" 12 | }, 13 | "IIS Express": { 14 | "commandName": "IISExpress", 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | } 20 | }, 21 | "Docker": { 22 | "commandName": "Docker", 23 | "launchBrowser": true, 24 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 25 | "publishAllPorts": true, 26 | "useSSL": true 27 | } 28 | }, 29 | "$schema": "https://json.schemastore.org/launchsettings.json", 30 | "iisSettings": { 31 | "windowsAuthentication": false, 32 | "anonymousAuthentication": true, 33 | "iisExpress": { 34 | "applicationUrl": "http://localhost:58037", 35 | "sslPort": 44387 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Lavcode.Asp/Services/AuthTokenService.cs: -------------------------------------------------------------------------------- 1 | using IdentityModel; 2 | using Microsoft.AspNetCore.Authentication.JwtBearer; 3 | using Microsoft.Extensions.Options; 4 | using Microsoft.IdentityModel.Tokens; 5 | using System.IdentityModel.Tokens.Jwt; 6 | using System.Security.Claims; 7 | 8 | namespace Lavcode.Asp.Services 9 | { 10 | public class AuthTokenService 11 | { 12 | private readonly JwtBearerOptions _jwtBearerOptions; 13 | private readonly SigningCredentials _signingCredentials; 14 | 15 | public AuthTokenService( 16 | IOptionsSnapshot jwtBearerOptions, 17 | SigningCredentials signingCredentials) 18 | { 19 | _jwtBearerOptions = jwtBearerOptions.Get(JwtBearerDefaults.AuthenticationScheme); 20 | _signingCredentials = signingCredentials; 21 | } 22 | 23 | public string CreateJwtToken() 24 | { 25 | var tokenDescriptor = new SecurityTokenDescriptor 26 | { 27 | Subject = new ClaimsIdentity(new List 28 | { 29 | new Claim("from", "lavcode"), 30 | }), 31 | Issuer = _jwtBearerOptions.TokenValidationParameters.ValidIssuer, 32 | Audience = _jwtBearerOptions.TokenValidationParameters.ValidAudience, 33 | Expires = DateTime.UtcNow.AddDays(90), 34 | SigningCredentials = _signingCredentials 35 | }; 36 | 37 | var handler = _jwtBearerOptions.SecurityTokenValidators.OfType().FirstOrDefault() 38 | ?? new JwtSecurityTokenHandler(); 39 | var securityToken = handler.CreateJwtSecurityToken(tokenDescriptor); 40 | var token = handler.WriteToken(securityToken); 41 | 42 | return token; 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Lavcode.Asp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "SecretKey": "your_secret_key", 10 | "ConnectionStrings": { 11 | "MSSQL": "Server=127.0.0.1;Database=Lavcode;uid=sa;Password=H;Encrypt=True;TrustServerCertificate=True;" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Common/CommonConstant.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Common 2 | { 3 | public static class CommonConstant 4 | { 5 | public static string HomeUrl { get; } = "https://lavcode.hal.wang"; 6 | public static string ToolsApiUrl { get; } = "https://tool.hal.wang/v3"; 7 | public static string Email { get; } = "support@hal.wang"; 8 | public static string PpUrl { get; } = $"{HomeUrl}/pp/zh/"; 9 | public static string DragPasswordHeader { get; } = "Lavcode_P"; 10 | 11 | public static string SqliteFileExtension { get; } = ".lc"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Common/Lavcode.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | Debug;Release;Debug_WithoutHello 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Lavcode.Common/RepositoryConstant.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Common 2 | { 3 | public static class RepositoryConstant 4 | { 5 | public static string GitAccount { get; } = "hal-wang"; 6 | public static string Repos { get; } = "Lavcode"; 7 | public static string FeedbackIssueTag { get; } = "Client Feedback"; 8 | public static int NoticeIssueNumber { get; } = 2; 9 | public static string GitHubUrl { get; } = "https://github.com"; 10 | public static string GitHubRepositoryUrl { get; } = $"{GitHubUrl}/{GitAccount}/{Repos}"; 11 | 12 | public static string GitStorageRepos { get; } = "LavcodeStorage"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Lavcode.IService/IConService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Lavcode.IService 5 | { 6 | public interface IConService : IDisposable 7 | { 8 | public Func UseProxy { get; } 9 | public Task Connect(object args); 10 | public Task Refresh(); 11 | public void SetProxy(Func useProxy); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.IService/IDataService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lavcode.IService 4 | { 5 | public interface IDataService 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Lavcode.IService/IFolderService.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace Lavcode.IService 6 | { 7 | public interface IFolderService : IDataService 8 | { 9 | public Task DeleteFolder(string folderId, bool record = true); 10 | public Task AddFolder(FolderModel folder); 11 | public Task UpdateFolder(FolderModel folder, bool skipIcon); 12 | public Task> GetFolders(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Lavcode.IService/IPasswordService.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace Lavcode.IService 6 | { 7 | public interface IPasswordService : IDataService 8 | { 9 | public Task DeletePassword(string passwordId, bool record = true); 10 | public Task AddPassword(PasswordModel password); 11 | public Task UpdatePassword(PasswordModel password, bool skipIcon, bool skipKvp); 12 | public Task> GetPasswords(string folderId); 13 | public Task> GetPasswords(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Lavcode.IService/Lavcode.IService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | Debug;Release;Debug_WithoutHello 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Lavcode.Model/FolderModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lavcode.Model 4 | { 5 | public class FolderModel 6 | { 7 | public FolderModel() 8 | { 9 | Icon = IconModel.GetDefault(StorageType.Folder); 10 | } 11 | 12 | public string Id { get; set; } 13 | public string Name { get; set; } 14 | public int Order { get; set; } 15 | public DateTimeOffset UpdatedAt { get; set; } 16 | 17 | public IconModel Icon { get; set; } 18 | 19 | public FolderModel DeepClone() 20 | { 21 | return new FolderModel() 22 | { 23 | Id = Id, 24 | Name = Name, 25 | Order = Order, 26 | UpdatedAt = UpdatedAt, 27 | Icon = Icon?.DeepClone(), 28 | }; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Lavcode.Model/IconType.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Model 2 | { 3 | public enum IconType 4 | { 5 | SegoeMDL2 = 1, 6 | Img = 2, 7 | Path = 3 8 | } 9 | } -------------------------------------------------------------------------------- /src/Lavcode.Model/KeyValuePairModel.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Model 2 | { 3 | public class KeyValuePairModel 4 | { 5 | public string Id { get; set; } 6 | public string PasswordId { get; set; } 7 | public string Key { get; set; } 8 | public string Value { get; set; } 9 | 10 | public KeyValuePairModel DeepClone() 11 | { 12 | return new KeyValuePairModel() 13 | { 14 | Id = Id, 15 | Key = Key, 16 | PasswordId = PasswordId, 17 | Value = Value, 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Lavcode.Model/Lavcode.Model.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | Debug;Release;Debug_WithoutHello 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Lavcode.Model/PasswordModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Lavcode.Model 6 | { 7 | public class PasswordModel 8 | { 9 | public PasswordModel() 10 | { 11 | Icon = IconModel.GetDefault(StorageType.Password); 12 | KeyValuePairs = new List(); 13 | } 14 | 15 | public string Id { get; set; } 16 | public string FolderId { get; set; } 17 | public string Title { get; set; } 18 | public string Value { get; set; } 19 | public string Remark { get; set; } 20 | public int Order { get; set; } 21 | public DateTimeOffset UpdatedAt { get; set; } 22 | 23 | public IconModel Icon { get; set; } 24 | public IList KeyValuePairs { get; set; } 25 | 26 | public PasswordModel DeepClone() 27 | { 28 | return new PasswordModel() 29 | { 30 | Id = Id, 31 | FolderId = FolderId, 32 | Title = Title, 33 | Value = Value, 34 | Remark = Remark, 35 | Order = Order, 36 | UpdatedAt = UpdatedAt, 37 | Icon = Icon?.DeepClone(), 38 | KeyValuePairs = KeyValuePairs?.Select(item => item.DeepClone())?.ToList() 39 | }; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Lavcode.Model/Provider.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Model 2 | { 3 | public enum Provider 4 | { 5 | Sqlite, 6 | GitHub, 7 | Gitee, 8 | Api 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Lavcode.Model/StorageType.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Model 2 | { 3 | public enum StorageType 4 | { 5 | Folder = 1, 6 | Password = 2, 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/CreateFolderDto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Lavcode.Service.Api.Dtos 4 | { 5 | public class CreateFolderDto 6 | { 7 | [JsonProperty("name")] 8 | public string Name { get; set; } 9 | 10 | [JsonProperty("icon")] 11 | public UpsertIconDto Icon { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/CreatePasswordDto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace Lavcode.Service.Api.Dtos 5 | { 6 | public class CreatePasswordDto 7 | { 8 | [JsonProperty("folderId")] 9 | public string FolderId { get; set; } 10 | 11 | [JsonProperty("title")] 12 | public string Title { get; set; } 13 | 14 | [JsonProperty("value")] 15 | public string Value { get; set; } 16 | 17 | [JsonProperty("remark")] 18 | public string Remark { get; set; } 19 | 20 | [JsonProperty("icon")] 21 | public UpsertIconDto Icon { get; set; } 22 | 23 | [JsonProperty("keyValuePairs")] 24 | public IList KeyValuePairs { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/GetFolderDto.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | using System; 4 | 5 | namespace Lavcode.Service.Api.Dtos 6 | { 7 | public class GetFolderDto 8 | { 9 | [JsonProperty("id")] 10 | public string Id { get; set; } 11 | 12 | [JsonProperty("name")] 13 | public string Name { get; set; } 14 | 15 | [JsonProperty("order")] 16 | public int Order { get; set; } 17 | 18 | [JsonProperty("updatedAt")] 19 | public long UpdatedAt { get; set; } 20 | 21 | [JsonProperty("icon")] 22 | public GetIconDto Icon { get; set; } 23 | 24 | public FolderModel ToModel() 25 | { 26 | return new FolderModel() 27 | { 28 | Id = Id, 29 | Name = Name, 30 | Order = Order, 31 | UpdatedAt = DateTimeOffset.FromUnixTimeMilliseconds(UpdatedAt), 32 | Icon = Icon.ToModel() 33 | }; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/GetIconDto.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | 4 | namespace Lavcode.Service.Api.Dtos 5 | { 6 | public class GetIconDto 7 | { 8 | [JsonProperty("id")] 9 | public string Id { get; set; } 10 | 11 | [JsonProperty("iconType")] 12 | public IconType IconType { get; set; } 13 | 14 | [JsonProperty("value")] 15 | public string Value { get; set; } 16 | 17 | public IconModel ToModel() 18 | { 19 | return new IconModel() 20 | { 21 | Id = Id, 22 | IconType = IconType, 23 | Value = Value 24 | }; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/GetKeyValuePairDto.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | 4 | namespace Lavcode.Service.Api.Dtos 5 | { 6 | public class GetKeyValuePairDto 7 | { 8 | [JsonProperty("id")] 9 | public string Id { get; set; } 10 | 11 | [JsonProperty("passwordId")] 12 | public string PasswordId { get; set; } 13 | 14 | [JsonProperty("key")] 15 | public string Key { get; set; } 16 | 17 | [JsonProperty("value")] 18 | public string Value { get; set; } 19 | 20 | public KeyValuePairModel ToModel() 21 | { 22 | return new KeyValuePairModel() 23 | { 24 | Id = Id, 25 | PasswordId = PasswordId, 26 | Key = Key, 27 | Value = Value 28 | }; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/GetPasswordDto.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace Lavcode.Service.Api.Dtos 8 | { 9 | public class GetPasswordDto 10 | { 11 | [JsonProperty("id")] 12 | public string Id { get; set; } 13 | 14 | [JsonProperty("folderId")] 15 | public string FolderId { get; set; } 16 | 17 | [JsonProperty("title")] 18 | public string Title { get; set; } 19 | 20 | [JsonProperty("value")] 21 | public string Value { get; set; } 22 | 23 | [JsonProperty("remark")] 24 | public string Remark { get; set; } 25 | 26 | [JsonProperty("order")] 27 | public int Order { get; set; } 28 | 29 | [JsonProperty("updatedAt")] 30 | public long UpdatedAt { get; set; } 31 | 32 | [JsonProperty("icon")] 33 | public GetIconDto Icon { get; set; } 34 | 35 | [JsonProperty("keyValuePairs")] 36 | public IList KeyValuePairs { get; set; } 37 | 38 | public PasswordModel ToModel() 39 | { 40 | return new PasswordModel() 41 | { 42 | Id = Id, 43 | FolderId = FolderId, 44 | Title = Title, 45 | Value = Value, 46 | Remark = Remark, 47 | Order = Order, 48 | UpdatedAt = DateTimeOffset.FromUnixTimeMilliseconds(UpdatedAt), 49 | Icon = Icon.ToModel(), 50 | KeyValuePairs = KeyValuePairs.Select(item => item.ToModel()).ToList() 51 | }; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/UpdateFolderDto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Lavcode.Service.Api.Dtos 4 | { 5 | public class UpdateFolderDto 6 | { 7 | [JsonProperty("name")] 8 | public string Name { get; set; } 9 | 10 | [JsonProperty("order")] 11 | public int Order { get; set; } 12 | 13 | [JsonProperty("icon")] 14 | public UpsertIconDto Icon { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/UpdatePasswordDto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace Lavcode.Service.Api.Dtos 5 | { 6 | public class UpdatePasswordDto 7 | { 8 | [JsonProperty("folderId")] 9 | public string FolderId { get; set; } 10 | 11 | [JsonProperty("title")] 12 | public string Title { get; set; } 13 | 14 | [JsonProperty("value")] 15 | public string Value { get; set; } 16 | 17 | [JsonProperty("remark")] 18 | public string Remark { get; set; } 19 | 20 | [JsonProperty("order")] 21 | public int Order { get; set; } 22 | 23 | [JsonProperty("icon")] 24 | public UpsertIconDto Icon { get; set; } 25 | 26 | [JsonProperty("keyValuePairs")] 27 | public IList KeyValuePairs { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/UpsertIconDto.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | 4 | namespace Lavcode.Service.Api.Dtos 5 | { 6 | public class UpsertIconDto 7 | { 8 | [JsonProperty("iconType")] 9 | public IconType IconType { get; set; } 10 | 11 | [JsonProperty("value")] 12 | public string Value { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Dtos/UpsertKeyValuePairDto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Lavcode.Service.Api.Dtos 4 | { 5 | public class UpsertKeyValuePairDto 6 | { 7 | [JsonProperty("key")] 8 | public string Key { get; set; } 9 | 10 | [JsonProperty("value")] 11 | public string Value { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Api/Lavcode.Service.Api.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Entities/FolderEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | using System; 4 | 5 | namespace Lavcode.Service.BaseGit.Entities 6 | { 7 | public class FolderEntity : IEntity 8 | { 9 | public string Id { get; set; } 10 | public string Name { get; set; } 11 | public int Order { get; set; } 12 | 13 | [JsonProperty("LastEditTime")] 14 | public DateTime UpdatedAt { get; set; } 15 | 16 | public FolderModel ToModel() 17 | { 18 | return new FolderModel() 19 | { 20 | Id = Id, 21 | Name = Name, 22 | Order = Order, 23 | UpdatedAt = UpdatedAt, 24 | }; 25 | } 26 | 27 | public static FolderEntity FromModel(FolderModel model) 28 | { 29 | return new FolderEntity() 30 | { 31 | Id = model.Id, 32 | Name = model.Name, 33 | Order = model.Order, 34 | UpdatedAt = model.UpdatedAt.DateTime, 35 | }; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Entities/IEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Lavcode.Service.BaseGit.Entities 6 | { 7 | public interface IEntity 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Entities/IconEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | 3 | namespace Lavcode.Service.BaseGit.Entities 4 | { 5 | public class IconEntity : IEntity 6 | { 7 | public string Id { get; set; } 8 | public IconType IconType { get; set; } 9 | public string Value { get; set; } 10 | 11 | public IconModel ToModel() 12 | { 13 | return new IconModel() 14 | { 15 | Id = Id, 16 | IconType = IconType, 17 | Value = Value 18 | }; 19 | } 20 | 21 | public static IconEntity FromModel(IconModel model) 22 | { 23 | return new IconEntity() 24 | { 25 | Id = model.Id, 26 | IconType = model.IconType, 27 | Value = model.Value 28 | }; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Entities/KeyValuePairEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | 4 | namespace Lavcode.Service.BaseGit.Entities 5 | { 6 | public class KeyValuePairEntity : IEntity 7 | { 8 | public string Id { get; set; } 9 | 10 | [JsonProperty("SourceId")] 11 | public string PasswordId { get; set; } 12 | public string Key { get; set; } 13 | public string Value { get; set; } 14 | 15 | public KeyValuePairModel ToModel() 16 | { 17 | return new KeyValuePairModel() 18 | { 19 | Id = Id, 20 | PasswordId = PasswordId, 21 | Key = Key, 22 | Value = Value 23 | }; 24 | } 25 | 26 | public static KeyValuePairEntity FromModel(KeyValuePairModel model) 27 | { 28 | return new KeyValuePairEntity() 29 | { 30 | Id = model.Id, 31 | PasswordId = model.PasswordId, 32 | Key = model.Key, 33 | Value = model.Value 34 | }; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Entities/PasswordEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Newtonsoft.Json; 3 | using System; 4 | 5 | namespace Lavcode.Service.BaseGit.Entities 6 | { 7 | public class PasswordEntity : IEntity 8 | { 9 | public string Id { get; set; } 10 | public string FolderId { get; set; } 11 | public string Title { get; set; } 12 | public string Value { get; set; } 13 | public string Remark { get; set; } 14 | public int Order { get; set; } 15 | 16 | [JsonProperty("LastEditTime")] 17 | public DateTime UpdatedAt { get; set; } 18 | 19 | public PasswordModel ToModel() 20 | { 21 | return new PasswordModel() 22 | { 23 | Id = Id, 24 | FolderId = FolderId, 25 | Title = Title, 26 | Value = Value, 27 | Remark = Remark, 28 | Order = Order, 29 | UpdatedAt = UpdatedAt 30 | }; 31 | } 32 | 33 | public static PasswordEntity FromModel(PasswordModel model) 34 | { 35 | return new PasswordEntity() 36 | { 37 | Id = model.Id, 38 | FolderId = model.FolderId, 39 | Title = model.Title, 40 | Value = model.Value, 41 | Remark = model.Remark, 42 | Order = model.Order, 43 | UpdatedAt = model.UpdatedAt.DateTime 44 | }; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Lavcode.Service.BaseGit.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | Debug;Release;Debug_WithoutHello 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Models/CommentItem.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Service.BaseGit.Models 2 | { 3 | public class CommentItem 4 | { 5 | public long Id { get; set; } 6 | public T Value { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Models/IssueItem.cs: -------------------------------------------------------------------------------- 1 | using OneOf; 2 | using System.Collections.Generic; 3 | 4 | namespace Lavcode.Service.BaseGit.Models 5 | { 6 | public class IssueItem 7 | { 8 | public long IssueId { get; set; } 9 | public OneOf IssueNumber { get; set; } 10 | public string Title { get; set; } 11 | public IList> Comments { get; set; } 12 | } 13 | 14 | public class IssueItem : IssueItem 15 | { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Lavcode.Service.BaseGit/Models/RepositoryItem.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Service.BaseGit.Models 2 | { 3 | public class RepositoryItem 4 | { 5 | public long Id { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Lavcode.Service.GitHub/Lavcode.Service.GitHub.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | Debug;Release;Debug_WithoutHello 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Gitee/Lavcode.Service.Gitee.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | Debug;Release;Debug_WithoutHello 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/DelectedService.cs: -------------------------------------------------------------------------------- 1 | using HTools; 2 | using Lavcode.IService; 3 | using Lavcode.Service.Sqlite.Entities; 4 | using SQLite; 5 | using System.Collections.Generic; 6 | using System.Threading.Tasks; 7 | 8 | namespace Lavcode.Service.Sqlite 9 | { 10 | public class DelectedService 11 | { 12 | private readonly ConService _cs; 13 | private SQLiteConnection Connection => _cs.Connection; 14 | 15 | public DelectedService(IConService cs) 16 | { 17 | _cs = cs as ConService; 18 | } 19 | 20 | public async Task> GetDelectedItems() 21 | { 22 | List result = null; 23 | await TaskExtend.Run(() => 24 | { 25 | result = Connection.Table().ToList(); 26 | }); 27 | return result; 28 | } 29 | 30 | public async Task Add(DelectedEntity delectedItem) 31 | { 32 | await TaskExtend.Run(() => 33 | { 34 | Connection.Insert(delectedItem); 35 | }); 36 | } 37 | 38 | public async Task Add(IList delectedItems) 39 | { 40 | await TaskExtend.Run(() => 41 | { 42 | Connection.InsertAll(delectedItems); 43 | }); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/BeforeKeyValuePairEntity.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | 3 | namespace Lavcode.Service.Sqlite.Entities 4 | { 5 | [Table("KeyValuePair")] 6 | public class BeforeKeyValuePairEntity 7 | { 8 | public virtual int Id { get; set; } 9 | public virtual string SourceId { get; set; } 10 | public virtual string Key { get; set; } 11 | public virtual string Value { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/DelectedEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using SQLite; 3 | 4 | namespace Lavcode.Service.Sqlite.Entities 5 | { 6 | /// 7 | /// 记录已删除的文件夹或密码,用于备份恢复 8 | /// 9 | [Table("DelectedItem")] 10 | public class DelectedEntity 11 | { 12 | /// 13 | /// 默认构造函数,给Sqlite用 14 | /// 15 | public DelectedEntity() { } 16 | 17 | public DelectedEntity(string sourceId, StorageType storageType) 18 | { 19 | Id = sourceId; 20 | StorageType = storageType; 21 | } 22 | 23 | [PrimaryKey] 24 | public string Id { get; set; } 25 | 26 | /// 27 | /// 文件夹还是密码 28 | /// 29 | public StorageType StorageType { get; set; } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/FolderEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using SQLite; 3 | using System; 4 | 5 | namespace Lavcode.Service.Sqlite.Entities 6 | { 7 | [Table("Folder")] 8 | public class FolderEntity 9 | { 10 | [PrimaryKey] 11 | public string Id { get; set; } 12 | 13 | [MaxLength(100)] 14 | public string Name { get; set; } 15 | 16 | public int Order { get; set; } 17 | 18 | [Column("LastEditTime")] 19 | public DateTime UpdatedAt { get; set; } 20 | 21 | public FolderModel ToModel() 22 | { 23 | return new FolderModel() 24 | { 25 | Id = Id, 26 | Name = Name, 27 | Order = Order, 28 | UpdatedAt = UpdatedAt, 29 | }; 30 | } 31 | 32 | public static FolderEntity FromModel(FolderModel model) 33 | { 34 | return new FolderEntity() 35 | { 36 | Id = model.Id, 37 | Name = model.Name, 38 | Order = model.Order, 39 | UpdatedAt = model.UpdatedAt.DateTime, 40 | }; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/IconEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using SQLite; 3 | 4 | namespace Lavcode.Service.Sqlite.Entities 5 | { 6 | [Table("Icon")] 7 | public class IconEntity 8 | { 9 | [PrimaryKey] 10 | public string Id { get; set; } 11 | 12 | /// 13 | /// 图标类型 14 | /// 15 | public IconType IconType { get; set; } 16 | 17 | /// 18 | /// 字体:1字符+字体名称 19 | /// 图片:Base64字符串 20 | /// 21 | [MaxLength(1024 * 1024 * 10)] 22 | public string Value { get; set; } 23 | 24 | public IconModel ToModel() 25 | { 26 | return new IconModel() 27 | { 28 | Id = Id, 29 | IconType = IconType, 30 | Value = Value 31 | }; 32 | } 33 | 34 | public static IconEntity FromModel(IconModel model) 35 | { 36 | return new IconEntity() 37 | { 38 | Id = model.Id, 39 | IconType = model.IconType, 40 | Value = model.Value 41 | }; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/KeyValuePairEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using SQLite; 3 | 4 | namespace Lavcode.Service.Sqlite.Entities 5 | { 6 | [Table("KeyValuePair")] 7 | public class KeyValuePairEntity 8 | { 9 | [PrimaryKey] 10 | public string Id { get; set; } 11 | 12 | [Column("SourceId")] 13 | public string PasswordId { get; set; } 14 | public string Key { get; set; } 15 | public string Value { get; set; } 16 | 17 | public KeyValuePairModel ToModel() 18 | { 19 | return new KeyValuePairModel() 20 | { 21 | Id = Id, 22 | PasswordId = PasswordId, 23 | Key = Key, 24 | Value = Value 25 | }; 26 | } 27 | 28 | public static KeyValuePairEntity FromModel(KeyValuePairModel model) 29 | { 30 | return new KeyValuePairEntity() 31 | { 32 | Id = model.Id, 33 | PasswordId = model.PasswordId, 34 | Key = model.Key, 35 | Value = model.Value 36 | }; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/PasswordEntity.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using SQLite; 3 | using System; 4 | 5 | namespace Lavcode.Service.Sqlite.Entities 6 | { 7 | [Table("Password")] 8 | public class PasswordEntity 9 | { 10 | [PrimaryKey] 11 | public string Id { get; set; } 12 | 13 | public string FolderId { get; set; } 14 | 15 | [MaxLength(100)] 16 | public string Title { get; set; } 17 | 18 | /// 19 | /// 密码 20 | /// 21 | [MaxLength(100)] 22 | public string Value { get; set; } 23 | 24 | [MaxLength(500)] 25 | public string Remark { get; set; } 26 | 27 | public int Order { get; set; } 28 | 29 | [Column("LastEditTime")] 30 | public DateTime UpdatedAt { get; set; } 31 | 32 | public PasswordModel ToModel() 33 | { 34 | return new PasswordModel() 35 | { 36 | Id = Id, 37 | FolderId = FolderId, 38 | Title = Title, 39 | Value = Value, 40 | Remark = Remark, 41 | Order = Order, 42 | UpdatedAt = UpdatedAt, 43 | }; 44 | } 45 | 46 | public static PasswordEntity FromModel(PasswordModel model) 47 | { 48 | return new PasswordEntity() 49 | { 50 | Id = model.Id, 51 | FolderId = model.FolderId, 52 | Title = model.Title, 53 | Value = model.Value, 54 | Remark = model.Remark, 55 | Order = model.Order, 56 | UpdatedAt = model.UpdatedAt.DateTime 57 | }; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Entities/TableInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Service.Sqlite.Entities 2 | { 3 | internal class TableInfo 4 | { 5 | public string Name { get; set; } 6 | public string Type { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/Lavcode.Service.Sqlite.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | Debug;Release;Debug_WithoutHello 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Lavcode.Service.Sqlite/SqliteHelper.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.IService; 2 | using System; 3 | using System.Threading.Tasks; 4 | 5 | namespace Lavcode.Service.Sqlite 6 | { 7 | public class SqliteHelper : IDisposable 8 | { 9 | public IConService ConService { get; private set; } 10 | public IFolderService FolderService { get; private set; } 11 | public IPasswordService PasswordService { get; private set; } 12 | public DelectedService DeletedService { get; private set; } 13 | 14 | private SqliteHelper() { } 15 | public async static Task OpenAsync(string filePath) 16 | { 17 | var result = new SqliteHelper 18 | { 19 | ConService = new ConService(), 20 | }; 21 | await result.ConService.Connect(new { FilePath = filePath }); 22 | 23 | result.FolderService = new FolderService(result.ConService); 24 | result.PasswordService = new PasswordService(result.ConService); 25 | result.DeletedService = new DelectedService(result.ConService); 26 | 27 | return result; 28 | } 29 | 30 | public void Dispose() 31 | { 32 | ConService?.Dispose(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # IDE0058: Expression value is never used 4 | dotnet_diagnostic.IDE0058.severity = none 5 | 6 | # IDE0011: Add braces 7 | dotnet_diagnostic.IDE0011.severity = none 8 | 9 | # IDE0008: Use explicit type 10 | dotnet_diagnostic.IDE0008.severity = none 11 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/BadgeLogo.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/LargeTile.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SmallTile.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-16.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-24.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-256.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-32.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-lightunplated_targetsize-48.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-24.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-32.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-24.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-32.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-125.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-150.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/Visual/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/alipay.jpg -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/logo_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/logo_alpha.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/qq_group.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/qq_group.jpg -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/wechat_qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/wechat_qr.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/windows_hello_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/windows_hello_10.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/windows_hello_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/windows_hello_11.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/Images/wxpay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/Images/wxpay.jpg -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Assets/StoreLogo.backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Assets/StoreLogo.backup.png -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Controls/Header.xaml: -------------------------------------------------------------------------------- 1 |  16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Controls/Header.xaml.cs: -------------------------------------------------------------------------------- 1 | using Windows.UI.Xaml; 2 | using Windows.UI.Xaml.Controls; 3 | 4 | namespace Lavcode.Uwp.Controls 5 | { 6 | public sealed partial class Header : ContentControl 7 | { 8 | public Header() 9 | { 10 | this.InitializeComponent(); 11 | } 12 | 13 | 14 | 15 | public string Text 16 | { 17 | get { return (string)GetValue(TextProperty); } 18 | set { SetValue(TextProperty, value); } 19 | } 20 | 21 | // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... 22 | public static readonly DependencyProperty TextProperty = 23 | DependencyProperty.Register("Text", typeof(string), typeof(Header), new PropertyMetadata(string.Empty)); 24 | 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Controls/Issue/IssueList.xaml.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using Windows.System; 5 | using Windows.UI.Xaml; 6 | using Windows.UI.Xaml.Controls; 7 | 8 | namespace Lavcode.Uwp.Controls.Issue 9 | { 10 | public sealed partial class IssueList : UserControl 11 | { 12 | public IssueList() 13 | { 14 | this.InitializeComponent(); 15 | } 16 | 17 | public IEnumerable Issues 18 | { 19 | get { return (IEnumerable)GetValue(IssuesProperty); } 20 | set { SetValue(IssuesProperty, value); } 21 | } 22 | 23 | // Using a DependencyProperty as the backing store for Issues. This enables animation, styling, binding, etc... 24 | public static readonly DependencyProperty IssuesProperty = 25 | DependencyProperty.Register("Issues", typeof(IEnumerable), typeof(IssueList), new PropertyMetadata(null)); 26 | 27 | private async void MarkdownText_LinkClicked(object sender, Microsoft.Toolkit.Uwp.UI.Controls.LinkClickedEventArgs e) 28 | { 29 | await Launcher.LaunchUriAsync(new Uri(e.Link)); 30 | } 31 | 32 | private async void AuthorButton_Click(object sender, RoutedEventArgs e) 33 | { 34 | var issue = (sender as FrameworkElement).DataContext as Octokit.Issue; 35 | await Launcher.LaunchUriAsync(new Uri($"{RepositoryConstant.GitHubUrl}/{issue.User.Login}")); 36 | } 37 | 38 | private async void ListView_ItemClick(object sender, ItemClickEventArgs e) 39 | { 40 | if (e.ClickedItem is not Octokit.Issue issue) 41 | { 42 | return; 43 | } 44 | 45 | await Launcher.LaunchUriAsync(new Uri(issue.HtmlUrl)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Controls/Logo.xaml.cs: -------------------------------------------------------------------------------- 1 | using Windows.UI.Xaml.Controls; 2 | 3 | namespace Lavcode.Uwp.Controls 4 | { 5 | public sealed partial class Logo : UserControl 6 | { 7 | public Logo() 8 | { 9 | this.InitializeComponent(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Converters/ProviderConverter.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using System; 3 | using Windows.UI.Xaml.Data; 4 | 5 | namespace Lavcode.Uwp.Converters 6 | { 7 | internal class ProviderConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, string language) 10 | { 11 | if (value is not Provider provider) return ""; 12 | return provider switch 13 | { 14 | Provider.Sqlite => "本地", 15 | Provider.GitHub => "GitHub", 16 | Provider.Gitee => "Gitee", 17 | Provider.Api => "云接口", 18 | _ => "", 19 | }; 20 | } 21 | 22 | public object ConvertBack(object value, Type targetType, object parameter, string language) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Global.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Uwp.Helpers; 2 | using Windows.ApplicationModel; 3 | 4 | namespace Lavcode.Uwp 5 | { 6 | public static class Global 7 | { 8 | public static string Version { get; } = $"{Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}"; 9 | 10 | public static bool IsNetworked => SettingHelper.Instance.Provider != Model.Provider.Sqlite; 11 | public static bool IsGit => SettingHelper.Instance.Provider == Model.Provider.GitHub || SettingHelper.Instance.Provider == Model.Provider.Gitee; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Helpers/CommandLauncher.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | 3 | namespace Lavcode.Uwp.Helpers 4 | { 5 | public class CommandLauncher 6 | { 7 | private readonly string _arguments; 8 | public CommandLauncher(string arguments) 9 | { 10 | _arguments = arguments; 11 | } 12 | 13 | public string[] Arguments => _arguments?.Split(' '); 14 | 15 | public Provider? Provider 16 | { 17 | get 18 | { 19 | if (Arguments == null || Arguments.Length < 1) 20 | { 21 | return null; 22 | } 23 | 24 | var pStr = Arguments[1]; 25 | if ( 26 | pStr.ToLower() == Model.Provider.Gitee.ToString().ToLower() || 27 | pStr.ToLower() == "码云") 28 | { 29 | return Model.Provider.Gitee; 30 | } 31 | else if ( 32 | pStr.ToLower() == Model.Provider.GitHub.ToString().ToLower() || 33 | pStr.ToLower() == "git" || 34 | pStr.ToLower() == "gayhub") // LOL 35 | { 36 | return Model.Provider.GitHub; 37 | } 38 | else if ( 39 | pStr.ToLower() == Model.Provider.Sqlite.ToString().ToLower() || 40 | pStr.ToLower() == "local" || 41 | pStr.ToLower() == "本地") 42 | { 43 | return Model.Provider.Sqlite; 44 | } 45 | else if ( 46 | pStr.ToLower() == Model.Provider.Api.ToString().ToLower() || 47 | pStr.ToLower() == "net" || 48 | pStr.ToLower() == "network") 49 | { 50 | return Model.Provider.Api; 51 | } 52 | else 53 | { 54 | return null; 55 | } 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Helpers/ExitHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Windows.UI.Core.Preview; 6 | using Windows.UI.Xaml; 7 | 8 | namespace Lavcode.Uwp.Helpers 9 | { 10 | public class ExitHandler 11 | { 12 | private ExitHandler() { } 13 | public static ExitHandler Instance { get; } = new ExitHandler(); 14 | 15 | public void Register() 16 | { 17 | SystemNavigationManagerPreview.GetForCurrentView().CloseRequested -= this.OnCloseRequest; 18 | Requests.Clear(); 19 | 20 | SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += this.OnCloseRequest; 21 | } 22 | 23 | private async void OnCloseRequest(object sender, SystemNavigationCloseRequestedPreviewEventArgs e) 24 | { 25 | e.Handled = true; 26 | 27 | int level = -1; 28 | for (var i = 0; i < Requests.Count; i++) 29 | { 30 | if (!Requests.Any(req => req.level > level)) 31 | { 32 | break; 33 | } 34 | level = Requests.Where(req => req.level > level).Min(req => req.level); 35 | var request = Requests.First(req => req.level == level); 36 | if (!await request.Func()) 37 | { 38 | return; 39 | } 40 | } 41 | Application.Current.Exit(); 42 | } 43 | 44 | public void Add(Func> func, int level) 45 | { 46 | Requests.Add(new(func, level)); 47 | } 48 | 49 | public void Remove(Func> func) 50 | { 51 | Requests.RemoveAll(item => item.Func == func); 52 | } 53 | 54 | /// 55 | /// true: 执行后面的回调 56 | /// false: 不退出并且不执行后面的回调 57 | /// 58 | private List<(Func> Func, int level)> Requests { get; } = new(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Helpers/GitHubHelper.cs: -------------------------------------------------------------------------------- 1 | using Octokit; 2 | 3 | namespace Lavcode.Uwp.Helpers 4 | { 5 | public static class GitHubHelper 6 | { 7 | public static GitHubClient GetBaseClient(string name) 8 | { 9 | return new GitHubClient(new ProductHeaderValue(name)); 10 | } 11 | 12 | public static GitHubClient GetAuthClient(string name, string token) 13 | { 14 | var credentials = new Credentials(token, AuthenticationType.Oauth); 15 | return new GitHubClient(new ProductHeaderValue(name)) { Credentials = credentials }; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Helpers/NetLoadingHelper.cs: -------------------------------------------------------------------------------- 1 | using HTools.Uwp.Helpers; 2 | using System; 3 | using System.Threading.Tasks; 4 | 5 | namespace Lavcode.Uwp.Helpers 6 | { 7 | public static class NetLoadingHelper 8 | { 9 | public static async Task Invoke(Func> func, string loadingStr = "", bool exMsg = true) 10 | { 11 | if (Global.IsNetworked) 12 | { 13 | LoadingHelper.Show(loadingStr); 14 | } 15 | try 16 | { 17 | return await func(); 18 | } 19 | catch (Exception ex) 20 | { 21 | if (exMsg) 22 | { 23 | MessageHelper.ShowError(ex); 24 | return default; 25 | } 26 | else 27 | { 28 | throw; 29 | } 30 | } 31 | finally 32 | { 33 | if (Global.IsNetworked) 34 | { 35 | LoadingHelper.Hide(); 36 | } 37 | } 38 | } 39 | 40 | public static async Task Invoke(Func func, string loadingStr = "", bool exMsg = true) 41 | { 42 | await Invoke(async () => 43 | { 44 | await func(); 45 | return null; 46 | }, loadingStr, exMsg); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Helpers/UpdateHelper.cs: -------------------------------------------------------------------------------- 1 | using HTools; 2 | using System; 3 | using System.Diagnostics; 4 | using System.Threading.Tasks; 5 | using Windows.Services.Store; 6 | 7 | namespace Lavcode.Uwp.Helpers 8 | { 9 | public static class UpdateHelper 10 | { 11 | public static async Task DownloadAndInstallAllUpdatesAsync() 12 | { 13 | var result = false; 14 | await TaskExtend.Run(async () => 15 | { 16 | try 17 | { 18 | var context = StoreContext.GetDefault(); 19 | var updates = await context.GetAppAndOptionalStorePackageUpdatesAsync(); 20 | if (updates.Count > 0) 21 | { 22 | var downloadResult = await context.RequestDownloadStorePackageUpdatesAsync(updates); 23 | if (downloadResult.OverallState == StorePackageUpdateState.Completed) 24 | { 25 | await context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates); 26 | } 27 | } 28 | result = updates.Count > 0; 29 | } 30 | catch (Exception ex) 31 | { 32 | Debug.WriteLine(ex); 33 | result = false; 34 | } 35 | }); 36 | return result; 37 | } 38 | 39 | public static async void DownloadAndInstallAllUpdatesBackground() 40 | { 41 | await DownloadAndInstallAllUpdatesAsync(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Lavcode.Uwp_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-wang/Lavcode/a540fa770c6fa517d92647f4e4163195de54618d/src/Lavcode.Uwp/Lavcode.Uwp_TemporaryKey.pfx -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Auth/AuthPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using HTools.Uwp.Helpers; 2 | using Lavcode.Uwp.Helpers; 3 | using Windows.UI.Core; 4 | using Windows.UI.Xaml; 5 | using Windows.UI.Xaml.Controls; 6 | using Windows.UI.Xaml.Navigation; 7 | 8 | namespace Lavcode.Uwp.Modules.Auth 9 | { 10 | public sealed partial class AuthPage : Page 11 | { 12 | private bool _autoLogin = true; 13 | 14 | public AuthPage() 15 | { 16 | this.InitializeComponent(); 17 | TitleBarHelper.SetTitleBar(); 18 | 19 | Loaded += AuthPage_Loaded; 20 | } 21 | 22 | private void AuthPage_Loaded(object sender, RoutedEventArgs e) 23 | { 24 | if (_autoLogin && SettingHelper.Instance.IsAutoLogin) 25 | { 26 | VM.TryLogin(); 27 | } 28 | } 29 | 30 | protected override void OnNavigatedTo(NavigationEventArgs e) 31 | { 32 | base.OnNavigatedTo(e); 33 | 34 | if (e.Parameter is bool b) 35 | { 36 | _autoLogin = b; 37 | } 38 | 39 | Frame.BackStack.Clear(); 40 | SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed; 41 | } 42 | 43 | public AuthViewModel VM { get; } = new AuthViewModel(); 44 | } 45 | } -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Auth/OAuthLoginDialog.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Auth/WindowsHelloDisabled.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Toolkit.Uwp.Helpers; 2 | using Windows.Foundation; 3 | using Windows.UI.Xaml; 4 | using Windows.UI.Xaml.Controls; 5 | 6 | namespace Lavcode.Uwp.Modules.Auth 7 | { 8 | public sealed partial class WindowsHelloDisabled : UserControl 9 | { 10 | public WindowsHelloDisabled() 11 | { 12 | this.InitializeComponent(); 13 | } 14 | 15 | public bool IsWin11 => SystemInformation.Instance.OperatingSystemVersion.Build >= 22000; 16 | 17 | public event TypedEventHandler OnRetry; 18 | 19 | private void RetryButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) 20 | { 21 | OnRetry?.Invoke(this, e); 22 | } 23 | 24 | private void ReferenceBtn_Click(object sender, RoutedEventArgs e) 25 | { 26 | ReferenceTip.IsOpen = true; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Feedback/FeedbackDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using HTools.Uwp.Helpers; 2 | using Lavcode.Common; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Octokit; 5 | using System; 6 | using Windows.System; 7 | using Windows.UI.Xaml; 8 | using Windows.UI.Xaml.Controls; 9 | 10 | namespace Lavcode.Uwp.Modules.Feedback 11 | { 12 | public sealed partial class FeedbackDialog : ContentDialog, IResultDialog 13 | { 14 | public FeedbackDialog() 15 | { 16 | DataContext = VM; 17 | InitializeComponent(); 18 | } 19 | 20 | public FeedbackDialogViewModel VM { get; } = ServiceProvider.Services.GetService(); 21 | 22 | public bool IsLoading 23 | { 24 | get => (bool)GetValue(IsLoadingProperty); 25 | set => SetValue(IsLoadingProperty, value); 26 | } 27 | 28 | // Using a DependencyProperty as the backing store for IsLoading. This enables animation, styling, binding, etc... 29 | public static readonly DependencyProperty IsLoadingProperty = 30 | DependencyProperty.Register("IsLoading", typeof(bool), typeof(FeedbackDialog), new PropertyMetadata(false)); 31 | 32 | private async void LayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) 33 | { 34 | args.Cancel = true; 35 | if (IsLoading) return; 36 | 37 | IsLoading = true; 38 | if (await VM.Feedback()) 39 | { 40 | this.Hide(VM.IssueResult); 41 | } 42 | IsLoading = false; 43 | } 44 | 45 | private async void Preview_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) 46 | { 47 | await new MarkdownPreview(VM.Content).QueueAsync(); 48 | } 49 | 50 | private async void Signup_Click(object sender, RoutedEventArgs e) 51 | { 52 | await Launcher.LaunchUriAsync(new Uri(RepositoryConstant.GitHubUrl, UriKind.Absolute)); 53 | } 54 | 55 | public Issue Result { get; set; } = null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Feedback/MarkdownPreview.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 15 | 16 | 17 | 18 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Feedback/MarkdownPreview.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.System; 3 | using Windows.UI.Xaml.Controls; 4 | 5 | namespace Lavcode.Uwp.Modules.Feedback 6 | { 7 | public sealed partial class MarkdownPreview : ContentDialog 8 | { 9 | public MarkdownPreview(string markdown) 10 | { 11 | InitializeComponent(); 12 | 13 | Markdown = markdown; 14 | } 15 | 16 | public string Markdown { get; } 17 | 18 | private async void MarkdownTextBlock_LinkClicked(object sender, Microsoft.Toolkit.Uwp.UI.Controls.LinkClickedEventArgs e) 19 | { 20 | if (Uri.TryCreate(e.Link, UriKind.Absolute, out Uri link)) 21 | { 22 | await Launcher.LaunchUriAsync(link); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/FirstUse/ProviderSelectButton.xaml: -------------------------------------------------------------------------------- 1 |  16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Git/GitInfo.xaml.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Common; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using System; 4 | using Windows.System; 5 | using Windows.UI.Xaml.Controls; 6 | 7 | namespace Lavcode.Uwp.Modules.Git 8 | { 9 | public sealed partial class GitInfo : UserControl 10 | { 11 | public GitInfo() 12 | { 13 | DataContext = VM; 14 | this.InitializeComponent(); 15 | 16 | Loaded += GitInfo_Loaded; 17 | } 18 | 19 | public GitInfoViewModel VM { get; } = ServiceProvider.Services.GetService(); 20 | 21 | private async void GitInfo_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) 22 | { 23 | await VM.Init(); 24 | } 25 | 26 | 27 | public async void HandleViewSourceCode() 28 | { 29 | await Launcher.LaunchUriAsync(new Uri(RepositoryConstant.GitHubRepositoryUrl)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Git/GitInfoViewModel.cs: -------------------------------------------------------------------------------- 1 | using HTools; 2 | using HTools.Uwp.Helpers; 3 | using Lavcode.Common; 4 | using Lavcode.Uwp.Helpers; 5 | using Microsoft.Toolkit.Mvvm.ComponentModel; 6 | using Octokit; 7 | using System; 8 | using System.Threading.Tasks; 9 | 10 | namespace Lavcode.Uwp.Modules 11 | { 12 | public class GitInfoViewModel : ObservableObject 13 | { 14 | private bool _loading = false; 15 | public bool Loading 16 | { 17 | get { return _loading; } 18 | set { SetProperty(ref _loading, value); } 19 | } 20 | 21 | private Repository _repository = null; 22 | public Repository Repository 23 | { 24 | get { return _repository; } 25 | set { SetProperty(ref _repository, value); } 26 | } 27 | 28 | public async Task Init() 29 | { 30 | if (Repository != null) 31 | { 32 | return; 33 | } 34 | 35 | Loading = true; 36 | await TaskExtend.SleepAsync(100); 37 | 38 | try 39 | { 40 | var github = GitHubHelper.GetBaseClient(RepositoryConstant.Repos); 41 | Repository = await github.Repository.Get(RepositoryConstant.GitAccount, RepositoryConstant.Repos); 42 | } 43 | catch (Exception ex) 44 | { 45 | MessageHelper.ShowError(ex, 0); 46 | return; 47 | } 48 | finally 49 | { 50 | Loading = false; 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Git/Icon.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Git/Icon.xaml.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Common; 2 | using System; 3 | using Windows.System; 4 | using Windows.UI.Xaml; 5 | using Windows.UI.Xaml.Controls; 6 | using Windows.UI.Xaml.Media; 7 | 8 | namespace Lavcode.Uwp.Modules.Git 9 | { 10 | public sealed partial class Icon : UserControl 11 | { 12 | public Icon() 13 | { 14 | this.InitializeComponent(); 15 | } 16 | 17 | public int Count 18 | { 19 | get { return (int)GetValue(CountProperty); } 20 | set { SetValue(CountProperty, value); } 21 | } 22 | 23 | // Using a DependencyProperty as the backing store for Count. This enables animation, styling, binding, etc... 24 | public static readonly DependencyProperty CountProperty = 25 | DependencyProperty.Register("Count", typeof(int), typeof(Icon), new PropertyMetadata(0)); 26 | 27 | public Geometry Data 28 | { 29 | get { return (Geometry)GetValue(DataProperty); } 30 | set { SetValue(DataProperty, value); } 31 | } 32 | 33 | // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... 34 | public static readonly DependencyProperty DataProperty = 35 | DependencyProperty.Register("Data", typeof(Geometry), typeof(Icon), new PropertyMetadata(null)); 36 | 37 | private async void PathButton_Click(object sender, RoutedEventArgs e) 38 | { 39 | await Launcher.LaunchUriAsync(new Uri(RepositoryConstant.GitHubRepositoryUrl)); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Guide/GuideItem.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml.Controls; 2 | using Windows.UI.Xaml; 3 | 4 | namespace Lavcode.Uwp.Modules.Guide 5 | { 6 | public class GuideItem 7 | { 8 | public FrameworkElement Target { get; set; } 9 | public string Title { get; set; } 10 | public string Content { get; set; } 11 | public TeachingTipPlacementMode Placement { get; set; } = TeachingTipPlacementMode.Auto; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Guide/GuideSettingMapItem.cs: -------------------------------------------------------------------------------- 1 | namespace Lavcode.Uwp.Modules.Guide 2 | { 3 | public class GuideSettingMapItem 4 | { 5 | public string Field { get; set; } 6 | public string[] Children { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/HelpDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Common; 2 | using System; 3 | using Windows.System; 4 | using Windows.UI.Xaml; 5 | using Windows.UI.Xaml.Controls; 6 | 7 | namespace Lavcode.Uwp.Modules 8 | { 9 | public sealed partial class HelpDialog : ContentDialog 10 | { 11 | public HelpDialog() 12 | { 13 | this.InitializeComponent(); 14 | } 15 | 16 | public string ReposUrl => RepositoryConstant.GitHubRepositoryUrl; 17 | 18 | public string AES256Url => "https://baike.baidu.com/item/高级加密标准"; 19 | 20 | private void Donate_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) 21 | { 22 | DonateFlyout.ShowAt(sender as FrameworkElement); 23 | FindName(nameof(Rating)); 24 | } 25 | 26 | private async void MoreHelp_Click(object sender, RoutedEventArgs e) 27 | { 28 | await Launcher.LaunchUriAsync(new Uri(CommonConstant.HomeUrl)); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Notices/NoticesPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using HTools.Uwp.Helpers; 2 | using Lavcode.Common; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using System; 5 | using Windows.System; 6 | using Windows.UI.Xaml; 7 | using Windows.UI.Xaml.Controls; 8 | 9 | namespace Lavcode.Uwp.Modules.Notices 10 | { 11 | public sealed partial class NoticesPage : Page 12 | { 13 | public NoticesPage() 14 | { 15 | DataContext = VM; 16 | this.InitializeComponent(); 17 | 18 | Loaded += NoticesPage_Loaded; 19 | } 20 | 21 | public NoticesViewModel VM { get; } = ServiceProvider.Services.GetService(); 22 | 23 | private async void NoticesPage_Loaded(object sender, RoutedEventArgs e) 24 | { 25 | await VM.Init(); 26 | } 27 | 28 | public string NoticesUrl { get; } = $"{RepositoryConstant.GitHubRepositoryUrl}/issues/{RepositoryConstant.NoticeIssueNumber}"; 29 | private async void Git_Click(object sender, RoutedEventArgs e) 30 | { 31 | try 32 | { 33 | var uriBing = new Uri(NoticesUrl); 34 | var success = await Launcher.LaunchUriAsync(new Uri(NoticesUrl)); 35 | } 36 | catch (Exception ex) 37 | { 38 | MessageHelper.ShowError(ex); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/FolderEditDialog.xaml: -------------------------------------------------------------------------------- 1 |  14 | 15 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/FolderItem.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | 3 | namespace Lavcode.Uwp.Modules.PasswordCore 4 | { 5 | public class FolderItem : IconItem 6 | { 7 | public FolderItem(FolderModel folder, IconModel icon = null) 8 | { 9 | Set(folder, icon); 10 | } 11 | 12 | public void Set(FolderModel folder, IconModel icon = null) 13 | { 14 | Folder = folder; 15 | Name = folder.Name; 16 | 17 | if (icon == null) 18 | { 19 | //后台设置图标 20 | SetIcon(folder.Icon); 21 | } 22 | else 23 | { 24 | Icon = icon; 25 | } 26 | } 27 | 28 | public FolderModel Folder { get; set; } 29 | 30 | private string _name = string.Empty; 31 | public string Name 32 | { 33 | get { return _name; } 34 | set { SetProperty(ref _name, value); } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/IconCtl/IconControlViewModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Toolkit.Mvvm.ComponentModel; 2 | using Windows.UI.Xaml.Media; 3 | 4 | namespace Lavcode.Uwp.Modules.PasswordCore.IconCtl 5 | { 6 | internal class IconControlViewModel : ObservableObject 7 | { 8 | private Geometry _pathIcon = null; 9 | public Geometry PathIcon 10 | { 11 | get { return _pathIcon; } 12 | set { SetProperty(ref _pathIcon, value); } 13 | } 14 | 15 | private ImageSource _imgIcon = null; 16 | public ImageSource ImgIcon 17 | { 18 | get { return _imgIcon; } 19 | set { SetProperty(ref _imgIcon, value); } 20 | } 21 | 22 | private string _segoeMDL2Icon = string.Empty; 23 | public string SegoeMDL2Icon 24 | { 25 | get { return _segoeMDL2Icon; } 26 | set { SetProperty(ref _segoeMDL2Icon, value); } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/IconItem.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Microsoft.Toolkit.Mvvm.ComponentModel; 3 | using System; 4 | using System.Diagnostics; 5 | using Windows.UI.Core; 6 | 7 | namespace Lavcode.Uwp.Modules.PasswordCore 8 | { 9 | public abstract class IconItem : ObservableObject 10 | { 11 | private IconModel _icon = null; 12 | public IconModel Icon 13 | { 14 | get { return _icon; } 15 | set { SetProperty(ref _icon, value); } 16 | } 17 | 18 | internal async void SetIcon(IconModel icon) 19 | { 20 | try 21 | { 22 | await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 23 | { 24 | try 25 | { 26 | Icon = icon; 27 | } 28 | catch (Exception ex) 29 | { 30 | Debug.WriteLine(ex); 31 | } 32 | }); 33 | 34 | } 35 | catch (Exception ex) 36 | { 37 | Debug.WriteLine(ex); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/PasswordGenerator.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Windows.Foundation; 3 | using Windows.UI.Xaml.Controls; 4 | 5 | namespace Lavcode.Uwp.Modules.PasswordCore 6 | { 7 | public sealed partial class PasswordGenerator : UserControl 8 | { 9 | public PasswordGenerator() 10 | { 11 | DataContext = VM; 12 | this.InitializeComponent(); 13 | } 14 | 15 | public PasswordGeneratorViewModel VM { get; } = ServiceProvider.Services.GetService(); 16 | 17 | public event TypedEventHandler PasswordChanged; 18 | 19 | private void GenerateBtn_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) 20 | { 21 | PasswordChanged?.Invoke(this, VM.GeneratePassword()); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/PasswordItem.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | 3 | namespace Lavcode.Uwp.Modules.PasswordCore 4 | { 5 | public class PasswordItem : IconItem 6 | { 7 | public PasswordItem(PasswordModel password, IconModel icon = null) 8 | { 9 | Set(password, icon); 10 | } 11 | 12 | public void Set(PasswordModel password, IconModel icon = null) 13 | { 14 | Password = password; 15 | Title = password.Title; 16 | Remark = password.Remark.Replace('\n', ' ').Replace('\r', ' '); 17 | 18 | if (icon == null) 19 | { 20 | //后台设置图标 21 | SetIcon(password.Icon); 22 | } 23 | else 24 | { 25 | Icon = icon; 26 | } 27 | } 28 | 29 | public PasswordModel Password { get; set; } 30 | 31 | private string _title = string.Empty; 32 | public string Title 33 | { 34 | get { return _title; } 35 | set { SetProperty(ref _title, value); } 36 | } 37 | 38 | private string _remark = string.Empty; 39 | public string Remark 40 | { 41 | get { return _remark; } 42 | set { SetProperty(ref _remark, value); } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/PasswordKeyValuePairCustomDialog.xaml: -------------------------------------------------------------------------------- 1 |  15 | 16 | 17 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/PasswordKeyValuePairCustomDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using HTools.Uwp.Helpers; 2 | using Windows.UI.Xaml; 3 | using Windows.UI.Xaml.Controls; 4 | 5 | namespace Lavcode.Uwp.Modules.PasswordCore 6 | { 7 | public sealed partial class PasswordKeyValuePairCustomDialog : ContentDialog 8 | { 9 | public PasswordKeyValuePairCustomDialog() 10 | { 11 | this.InitializeComponent(); 12 | } 13 | 14 | 15 | public string Key 16 | { 17 | get { return (string)GetValue(KeyProperty); } 18 | set { SetValue(KeyProperty, value); } 19 | } 20 | 21 | // Using a DependencyProperty as the backing store for Key. This enables animation, styling, binding, etc... 22 | public static readonly DependencyProperty KeyProperty = 23 | DependencyProperty.Register("Key", typeof(string), typeof(PasswordKeyValuePairCustomDialog), new PropertyMetadata(string.Empty)); 24 | 25 | 26 | private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) 27 | { 28 | if (string.IsNullOrEmpty(Key)) 29 | { 30 | args.Cancel = true; 31 | MessageHelper.ShowWarning("内容不能为空"); 32 | return; 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/PasswordKeyValuePairItem.cs: -------------------------------------------------------------------------------- 1 | using Lavcode.Model; 2 | using Microsoft.Toolkit.Mvvm.ComponentModel; 3 | 4 | namespace Lavcode.Uwp.Modules.PasswordCore 5 | { 6 | public class PasswordKeyValuePairItem : ObservableObject 7 | { 8 | public PasswordKeyValuePairItem(PasswordDetailViewModel vm) 9 | { 10 | VM = vm; 11 | } 12 | 13 | public PasswordDetailViewModel VM { get; } 14 | 15 | public PasswordKeyValuePairItem(KeyValuePairModel keyValuePair, PasswordDetailViewModel vm) 16 | : this(vm) 17 | { 18 | Key = keyValuePair.Key; 19 | Value = keyValuePair.Value; 20 | } 21 | 22 | private string _key = string.Empty; 23 | public string Key 24 | { 25 | get { return _key; } 26 | set { SetProperty(ref _key, value); } 27 | } 28 | 29 | private string _value = string.Empty; 30 | public string Value 31 | { 32 | get { return _value; } 33 | set { SetProperty(ref _value, value); } 34 | } 35 | 36 | private double _keyLength = 80; 37 | public double KeyLength 38 | { 39 | get { return _keyLength; } 40 | set { SetProperty(ref _keyLength, value); } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/PasswordCore/PasswordMoveToDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using HTools.Uwp.Helpers; 2 | using Lavcode.Model; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using System; 5 | using System.Collections.Generic; 6 | using Windows.UI.Xaml.Controls; 7 | 8 | namespace Lavcode.Uwp.Modules.PasswordCore 9 | { 10 | public sealed partial class PasswordMoveToDialog : ContentDialog, IResultDialog 11 | { 12 | public PasswordMoveToDialog(FolderModel curFolder, IReadOnlyList passwords) 13 | { 14 | DataContext = VM; 15 | this.InitializeComponent(); 16 | 17 | VM.Init(curFolder, passwords); 18 | } 19 | 20 | public PasswordMoveToViewModel VM { get; } = ServiceProvider.Services.GetService(); 21 | 22 | public bool Result { get; set; } = false; 23 | 24 | private async void LayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) 25 | { 26 | args.Cancel = true; 27 | 28 | try 29 | { 30 | if (await VM.MoveTo()) 31 | { 32 | this.Hide(true); 33 | } 34 | } 35 | catch (Exception ex) 36 | { 37 | MessageHelper.ShowError(ex); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Lavcode.Uwp/Modules/Rating.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 15 |