├── .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 |
8 |

9 |

10 |
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 |
33 |
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 | 
15 |
16 | ## 引导
17 |
18 | 首次打开软件,会有使用教程
19 |
20 | 跟着教程走一遍一般就会使用了
21 |
22 | ## 界面
23 |
24 | 主题色跟随系统,美观多彩的密码管理有木有!!!
25 |
26 | 上几张截图
27 |
28 | 
29 | 
30 | 
31 | 
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 | 
18 |
19 | 可浏览选择,也可在右上角处搜索,比如搜索“文件夹”可显示如下图片
20 |
21 | 
22 |
23 | ## 复制内容
24 |
25 | 找到想要的图标后,鼠标移上去,点“下载”
26 |
27 | 
28 |
29 | 再点击“复制”
30 |
31 | 
32 |
33 | ## 软件内使用
34 |
35 | 在设置路径图的弹窗中,直接粘贴到文本框中即可
36 |
37 | 
38 |
39 | 再点击确定就设置完成了
40 |
41 | 
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