mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 16:42:50 -05:00
Merge branch 'master' into flexible-collections/deprecate-custom-collection-perm
# Conflicts: # src/Api/AdminConsole/Controllers/OrganizationUsersController.cs # src/Api/Vault/AuthorizationHandlers/Collections/CollectionAuthorizationHandler.cs # test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs
This commit is contained in:
292
.vscode/launch.json
vendored
292
.vscode/launch.json
vendored
@ -7,94 +7,251 @@
|
|||||||
{
|
{
|
||||||
"name": "Min Server",
|
"name": "Min Server",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
"Identity",
|
"run-Identity",
|
||||||
"API"
|
"run-API"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"group": "AA_compounds",
|
"group": "AA_compounds",
|
||||||
"order": 1
|
"order": 1
|
||||||
},
|
},
|
||||||
|
"preLaunchTask": "buildIdentityApi",
|
||||||
"stopAll": true
|
"stopAll": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Admin, API, Identity",
|
"name": "Admin, API, Identity",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
"Admin",
|
"run-Admin",
|
||||||
"API",
|
"run-API",
|
||||||
"Identity"
|
"run-Identity"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"group": "AA_compounds",
|
"group": "AA_compounds",
|
||||||
"order": 3
|
"order": 3
|
||||||
},
|
},
|
||||||
|
"preLaunchTask": "buildIdentityApiAdmin",
|
||||||
"stopAll": true
|
"stopAll": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Full Server",
|
"name": "Full Server",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
"Admin",
|
"run-Admin",
|
||||||
"API",
|
"run-API",
|
||||||
"EventsProcessor",
|
"run-EventsProcessor",
|
||||||
"Identity",
|
"run-Identity",
|
||||||
"Sso",
|
"run-Sso",
|
||||||
"Icons",
|
"run-Icons",
|
||||||
"Billing",
|
"run-Billing",
|
||||||
"Notifications"
|
"run-Notifications"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"group": "AA_compounds",
|
"group": "AA_compounds",
|
||||||
"order": 4
|
"order": 4
|
||||||
},
|
},
|
||||||
|
"preLaunchTask": "buildFullServer",
|
||||||
"stopAll": true
|
"stopAll": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Self Host: Bit",
|
"name": "Self Host: Bit",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
"Admin-SelfHost",
|
"run-Admin-SelfHost",
|
||||||
"API-SelfHost",
|
"run-API-SelfHost",
|
||||||
"EventsProcessor-SelfHost",
|
"run-EventsProcessor-SelfHost",
|
||||||
"Identity-SelfHost",
|
"run-Identity-SelfHost",
|
||||||
"Sso-SelfHost",
|
"run-Sso-SelfHost",
|
||||||
"Notifications-SelfHost"
|
"run-Notifications-SelfHost"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"group": "AA_compounds",
|
"group": "AA_compounds",
|
||||||
"order": 2
|
"order": 2
|
||||||
},
|
},
|
||||||
|
"preLaunchTask": "buildSelfHostBit",
|
||||||
"stopAll": true
|
"stopAll": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Self Host: OSS",
|
"name": "Self Host: OSS",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
"Admin-SelfHost",
|
"run-Admin-SelfHost",
|
||||||
"API-SelfHost",
|
"run-API-SelfHost",
|
||||||
"EventsProcessor-SelfHost",
|
"run-EventsProcessor-SelfHost",
|
||||||
"Identity-SelfHost",
|
"run-Identity-SelfHost",
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"group": "AA_compounds",
|
"group": "AA_compounds",
|
||||||
"order": 99
|
"order": 99
|
||||||
},
|
},
|
||||||
|
"preLaunchTask": "buildSelfHostOss",
|
||||||
"stopAll": true
|
"stopAll": true
|
||||||
}
|
},
|
||||||
],
|
|
||||||
"configurations": [
|
|
||||||
{
|
{
|
||||||
"name": "Identity",
|
"name": "Admin",
|
||||||
|
"configurations": [
|
||||||
|
"run-Admin"
|
||||||
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"group": "cloud",
|
"group": "cloud",
|
||||||
"order": 10
|
},
|
||||||
|
"preLaunchTask": "buildAdmin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "API",
|
||||||
|
"configurations": [
|
||||||
|
"run-API"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildAPI",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Billing",
|
||||||
|
"configurations": [
|
||||||
|
"run-Billing"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildBilling",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Events Processor",
|
||||||
|
"configurations": [
|
||||||
|
"run-EventsProcessor"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildEventsProcessor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Icons",
|
||||||
|
"configurations": [
|
||||||
|
"run-Icons"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildIcons",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Identity",
|
||||||
|
"configurations": [
|
||||||
|
"run-Identity"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildIdentity",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Notifications",
|
||||||
|
"configurations": [
|
||||||
|
"run-Notifications"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildNotifications",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SSO",
|
||||||
|
"configurations": [
|
||||||
|
"run-Sso"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "cloud",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildSso",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Admin Self Host",
|
||||||
|
"configurations": [
|
||||||
|
"run-Admin-SelfHost"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "self-host",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildAdmin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "API Self Host",
|
||||||
|
"configurations": [
|
||||||
|
"run-API-SelfHost"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "self-host",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildAPI",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Events Processor Self Host",
|
||||||
|
"configurations": [
|
||||||
|
"run-EventsProcessor-SelfHost"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "self-host",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildEventsProcessor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Identity Self Host",
|
||||||
|
"configurations": [
|
||||||
|
"run-Identity-SelfHost"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "self-host",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildIdentity",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Notifications Self Host",
|
||||||
|
"configurations": [
|
||||||
|
"run-Notifications-SelfHost"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "self-host",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildNotifications",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SSO Self Host",
|
||||||
|
"configurations": [
|
||||||
|
"run-Sso-SelfHost"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"hidden": false,
|
||||||
|
"group": "self-host",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "buildSso",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"configurations": [
|
||||||
|
// Configurations represent run-only scenarios so that they can be used in multiple compounds
|
||||||
|
{
|
||||||
|
"name": "run-Identity",
|
||||||
|
"presentation": {
|
||||||
|
"hidden": true,
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildIdentity",
|
|
||||||
"program": "${workspaceFolder}/src/Identity/bin/Debug/net6.0/Identity.dll",
|
"program": "${workspaceFolder}/src/Identity/bin/Debug/net6.0/Identity.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Identity",
|
"cwd": "${workspaceFolder}/src/Identity",
|
||||||
@ -107,16 +264,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "API",
|
"name": "run-API",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 10
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildAPI",
|
|
||||||
"program": "${workspaceFolder}/src/Api/bin/Debug/net6.0/Api.dll",
|
"program": "${workspaceFolder}/src/Api/bin/Debug/net6.0/Api.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Api",
|
"cwd": "${workspaceFolder}/src/Api",
|
||||||
@ -129,16 +283,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Billing",
|
"name": "run-Billing",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 10
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildBilling",
|
|
||||||
"program": "${workspaceFolder}/src/Billing/bin/Debug/net6.0/Billing.dll",
|
"program": "${workspaceFolder}/src/Billing/bin/Debug/net6.0/Billing.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Billing",
|
"cwd": "${workspaceFolder}/src/Billing",
|
||||||
@ -151,16 +302,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Admin",
|
"name": "run-Admin",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 20
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildAdmin",
|
|
||||||
"OS-COMMENT4": "If you have changed target frameworks, make sure to update the program path.",
|
"OS-COMMENT4": "If you have changed target frameworks, make sure to update the program path.",
|
||||||
"program": "${workspaceFolder}/src/Admin/bin/Debug/net6.0/Admin.dll",
|
"program": "${workspaceFolder}/src/Admin/bin/Debug/net6.0/Admin.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
@ -175,16 +323,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Sso",
|
"name": "run-Sso",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 50
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildSso",
|
|
||||||
"program": "${workspaceFolder}/bitwarden_license/src/Sso/bin/Debug/net6.0/Sso.dll",
|
"program": "${workspaceFolder}/bitwarden_license/src/Sso/bin/Debug/net6.0/Sso.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/bitwarden_license/src/Sso",
|
"cwd": "${workspaceFolder}/bitwarden_license/src/Sso",
|
||||||
@ -197,16 +342,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EventsProcessor",
|
"name": "run-EventsProcessor",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 90
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildEventsProcessor",
|
|
||||||
"program": "${workspaceFolder}/src/EventsProcessor/bin/Debug/net6.0/EventsProcessor.dll",
|
"program": "${workspaceFolder}/src/EventsProcessor/bin/Debug/net6.0/EventsProcessor.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/EventsProcessor",
|
"cwd": "${workspaceFolder}/src/EventsProcessor",
|
||||||
@ -219,16 +361,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Icons",
|
"name": "run-Icons",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 90
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildIcons",
|
|
||||||
"program": "${workspaceFolder}/src/Icons/bin/Debug/net6.0/Icons.dll",
|
"program": "${workspaceFolder}/src/Icons/bin/Debug/net6.0/Icons.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Icons",
|
"cwd": "${workspaceFolder}/src/Icons",
|
||||||
@ -241,16 +380,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Notifications",
|
"name": "run-Notifications",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "cloud",
|
|
||||||
"order": 100
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildNotifications",
|
|
||||||
"program": "${workspaceFolder}/src/Notifications/bin/Debug/net6.0/Notifications.dll",
|
"program": "${workspaceFolder}/src/Notifications/bin/Debug/net6.0/Notifications.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Notifications",
|
"cwd": "${workspaceFolder}/src/Notifications",
|
||||||
@ -263,16 +399,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Identity-SelfHost",
|
"name": "run-Identity-SelfHost",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "self-host",
|
|
||||||
"order": 999
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildIdentity",
|
|
||||||
"program": "${workspaceFolder}/src/Identity/bin/Debug/net6.0/Identity.dll",
|
"program": "${workspaceFolder}/src/Identity/bin/Debug/net6.0/Identity.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Identity",
|
"cwd": "${workspaceFolder}/src/Identity",
|
||||||
@ -287,16 +420,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "API-SelfHost",
|
"name": "run-API-SelfHost",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "self-host",
|
|
||||||
"order": 999
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildAPI",
|
|
||||||
"program": "${workspaceFolder}/src/Api/bin/Debug/net6.0/Api.dll",
|
"program": "${workspaceFolder}/src/Api/bin/Debug/net6.0/Api.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Api",
|
"cwd": "${workspaceFolder}/src/Api",
|
||||||
@ -311,16 +441,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Admin-SelfHost",
|
"name": "run-Admin-SelfHost",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "self-host",
|
|
||||||
"order": 999
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildAdmin",
|
|
||||||
"OS-COMMENT4": "If you have changed target frameworks, make sure to update the program path.",
|
"OS-COMMENT4": "If you have changed target frameworks, make sure to update the program path.",
|
||||||
"program": "${workspaceFolder}/src/Admin/bin/Debug/net6.0/Admin.dll",
|
"program": "${workspaceFolder}/src/Admin/bin/Debug/net6.0/Admin.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
@ -337,16 +464,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Sso-SelfHost",
|
"name": "run-Sso-SelfHost",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "self-host",
|
|
||||||
"order": 999
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildSso",
|
|
||||||
"program": "${workspaceFolder}/bitwarden_license/src/Sso/bin/Debug/net6.0/Sso.dll",
|
"program": "${workspaceFolder}/bitwarden_license/src/Sso/bin/Debug/net6.0/Sso.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/bitwarden_license/src/Sso",
|
"cwd": "${workspaceFolder}/bitwarden_license/src/Sso",
|
||||||
@ -361,16 +485,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Notifications-SelfHost",
|
"name": "run-Notifications-SelfHost",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "self-host",
|
|
||||||
"order": 999
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildNotifications",
|
|
||||||
"program": "${workspaceFolder}/src/Notifications/bin/Debug/net6.0/Notifications.dll",
|
"program": "${workspaceFolder}/src/Notifications/bin/Debug/net6.0/Notifications.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Notifications",
|
"cwd": "${workspaceFolder}/src/Notifications",
|
||||||
@ -385,16 +506,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EventsProcessor-SelfHost",
|
"name": "run-EventsProcessor-SelfHost",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"group": "self-host",
|
|
||||||
"order": 999
|
|
||||||
},
|
},
|
||||||
"requireExactSource": true,
|
"requireExactSource": true,
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "buildEventsProcessor",
|
|
||||||
"program": "${workspaceFolder}/src/EventsProcessor/bin/Debug/net6.0/EventsProcessor.dll",
|
"program": "${workspaceFolder}/src/EventsProcessor/bin/Debug/net6.0/EventsProcessor.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/EventsProcessor",
|
"cwd": "${workspaceFolder}/src/EventsProcessor",
|
||||||
|
59
.vscode/tasks.json
vendored
59
.vscode/tasks.json
vendored
@ -1,6 +1,65 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "buildIdentityApi",
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"dependsOn": [
|
||||||
|
"buildIdentity",
|
||||||
|
"buildAPI"
|
||||||
|
],
|
||||||
|
"problemMatcher": [
|
||||||
|
"$msCompile"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "buildIdentityApiAdmin",
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"dependsOn": [
|
||||||
|
"buildIdentity",
|
||||||
|
"buildAPI",
|
||||||
|
"buildAdmin"
|
||||||
|
],
|
||||||
|
"problemMatcher": [
|
||||||
|
"$msCompile"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "buildFullServer",
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"dependsOn": [
|
||||||
|
"buildAdmin",
|
||||||
|
"buildAPI",
|
||||||
|
"buildEventsProcessor",
|
||||||
|
"buildIdentity",
|
||||||
|
"buildSso",
|
||||||
|
"buildIcons",
|
||||||
|
"buildBilling",
|
||||||
|
"buildNotifications",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "buildSelfHostBit",
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"dependsOn": [
|
||||||
|
"buildAdmin",
|
||||||
|
"buildAPI",
|
||||||
|
"buildEventsProcessor",
|
||||||
|
"buildIdentity",
|
||||||
|
"buildSso",
|
||||||
|
"buildNotifications",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "buildSelfHostOss",
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"dependsOn": [
|
||||||
|
"buildAdmin",
|
||||||
|
"buildAPI",
|
||||||
|
"buildEventsProcessor",
|
||||||
|
"buildIdentity",
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "buildIcons",
|
"label": "buildIcons",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>2023.10.2</Version>
|
<Version>2023.10.3</Version>
|
||||||
<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
|
<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
|
||||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
@ -162,6 +162,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -198,49 +216,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -318,10 +295,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -354,8 +331,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2450,10 +2427,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
|
@ -180,6 +180,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -216,49 +234,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -350,10 +327,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -386,8 +363,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2613,10 +2590,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2645,7 +2621,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
|
@ -184,6 +184,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -220,49 +238,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -354,10 +331,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -390,8 +367,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2617,10 +2594,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2648,7 +2624,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2656,7 +2632,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2668,9 +2644,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models;
|
using Bit.Core.Auth.Models;
|
||||||
@ -16,14 +18,15 @@ using Bit.Core.Tokens;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.Sso.Models;
|
using Bit.Sso.Models;
|
||||||
using Bit.Sso.Utilities;
|
using Bit.Sso.Utilities;
|
||||||
|
using Duende.IdentityServer;
|
||||||
|
using Duende.IdentityServer.Extensions;
|
||||||
|
using Duende.IdentityServer.Services;
|
||||||
|
using Duende.IdentityServer.Stores;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Extensions;
|
|
||||||
using IdentityServer4.Services;
|
|
||||||
using IdentityServer4.Stores;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using DIM = Duende.IdentityServer.Models;
|
||||||
|
|
||||||
namespace Bit.Sso.Controllers;
|
namespace Bit.Sso.Controllers;
|
||||||
|
|
||||||
@ -717,7 +720,7 @@ public class AccountController : Controller
|
|||||||
return (logoutId, logout?.PostLogoutRedirectUri, externalAuthenticationScheme);
|
return (logoutId, logout?.PostLogoutRedirectUri, externalAuthenticationScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNativeClient(IdentityServer4.Models.AuthorizationRequest context)
|
public bool IsNativeClient(DIM.AuthorizationRequest context)
|
||||||
{
|
{
|
||||||
return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal)
|
return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal)
|
||||||
&& !context.RedirectUri.StartsWith("http", StringComparison.Ordinal);
|
&& !context.RedirectUri.StartsWith("http", StringComparison.Ordinal);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Bit.Sso.Models;
|
using Bit.Sso.Models;
|
||||||
using IdentityServer4.Services;
|
using Duende.IdentityServer.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Diagnostics;
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using IdentityServer4;
|
using Duende.IdentityServer;
|
||||||
using IdentityServer4.Models;
|
using Duende.IdentityServer.Models;
|
||||||
|
|
||||||
namespace Bit.Sso.IdentityServer;
|
namespace Bit.Sso.IdentityServer;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using IdentityServer4.Models;
|
using Duende.IdentityServer.Models;
|
||||||
|
|
||||||
namespace Bit.Sso.Models;
|
namespace Bit.Sso.Models;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.SharedWeb.Utilities;
|
using Bit.SharedWeb.Utilities;
|
||||||
using Bit.Sso.Utilities;
|
using Bit.Sso.Utilities;
|
||||||
using IdentityServer4.Extensions;
|
using Duende.IdentityServer.Extensions;
|
||||||
using Microsoft.IdentityModel.Logging;
|
using Microsoft.IdentityModel.Logging;
|
||||||
using Stripe;
|
using Stripe;
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using IdentityServer4.Configuration;
|
using Duende.IdentityServer.Configuration;
|
||||||
using IdentityServer4.Services;
|
using Duende.IdentityServer.Services;
|
||||||
using IdentityServer4.Stores;
|
using Duende.IdentityServer.Stores;
|
||||||
using IdentityServer4.Validation;
|
using Duende.IdentityServer.Validation;
|
||||||
|
using DIR = Duende.IdentityServer.ResponseHandling;
|
||||||
|
|
||||||
namespace Bit.Sso.Utilities;
|
namespace Bit.Sso.Utilities;
|
||||||
|
|
||||||
public class DiscoveryResponseGenerator : IdentityServer4.ResponseHandling.DiscoveryResponseGenerator
|
public class DiscoveryResponseGenerator : DIR.DiscoveryResponseGenerator
|
||||||
{
|
{
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.Sso.Models;
|
using Bit.Sso.Models;
|
||||||
using Bit.Sso.Utilities;
|
using Bit.Sso.Utilities;
|
||||||
|
using Duende.IdentityServer;
|
||||||
|
using Duende.IdentityServer.Infrastructure;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Infrastructure;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -34,7 +34,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider
|
|||||||
private readonly Dictionary<string, DynamicAuthenticationScheme> _cachedSchemes;
|
private readonly Dictionary<string, DynamicAuthenticationScheme> _cachedSchemes;
|
||||||
private readonly Dictionary<string, DynamicAuthenticationScheme> _cachedHandlerSchemes;
|
private readonly Dictionary<string, DynamicAuthenticationScheme> _cachedHandlerSchemes;
|
||||||
private readonly SemaphoreSlim _semaphore;
|
private readonly SemaphoreSlim _semaphore;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
private DateTime? _lastSchemeLoad;
|
private DateTime? _lastSchemeLoad;
|
||||||
private IEnumerable<DynamicAuthenticationScheme> _schemesCopy = Array.Empty<DynamicAuthenticationScheme>();
|
private IEnumerable<DynamicAuthenticationScheme> _schemesCopy = Array.Empty<DynamicAuthenticationScheme>();
|
||||||
@ -50,7 +50,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider
|
|||||||
ILogger<DynamicAuthenticationSchemeProvider> logger,
|
ILogger<DynamicAuthenticationSchemeProvider> logger,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
SamlEnvironment samlEnvironment,
|
SamlEnvironment samlEnvironment,
|
||||||
IHttpContextAccessor httpContextAccessor)
|
IServiceProvider serviceProvider)
|
||||||
: base(options)
|
: base(options)
|
||||||
{
|
{
|
||||||
_oidcPostConfigureOptions = oidcPostConfigureOptions;
|
_oidcPostConfigureOptions = oidcPostConfigureOptions;
|
||||||
@ -77,7 +77,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider
|
|||||||
_cachedSchemes = new Dictionary<string, DynamicAuthenticationScheme>();
|
_cachedSchemes = new Dictionary<string, DynamicAuthenticationScheme>();
|
||||||
_cachedHandlerSchemes = new Dictionary<string, DynamicAuthenticationScheme>();
|
_cachedHandlerSchemes = new Dictionary<string, DynamicAuthenticationScheme>();
|
||||||
_semaphore = new SemaphoreSlim(1);
|
_semaphore = new SemaphoreSlim(1);
|
||||||
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
|
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CacheIsValid
|
private bool CacheIsValid
|
||||||
@ -324,7 +324,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider
|
|||||||
oidcOptions.Scope.AddIfNotExists(OpenIdConnectScopes.Acr);
|
oidcOptions.Scope.AddIfNotExists(OpenIdConnectScopes.Acr);
|
||||||
}
|
}
|
||||||
|
|
||||||
oidcOptions.StateDataFormat = new DistributedCacheStateDataFormatter(_httpContextAccessor, name);
|
oidcOptions.StateDataFormat = new DistributedCacheStateDataFormatter(_serviceProvider, name);
|
||||||
|
|
||||||
// see: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest (acr_values)
|
// see: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest (acr_values)
|
||||||
if (!string.IsNullOrWhiteSpace(config.AcrValues))
|
if (!string.IsNullOrWhiteSpace(config.AcrValues))
|
||||||
|
@ -4,8 +4,8 @@ using Bit.Core.Utilities;
|
|||||||
using Bit.SharedWeb.Utilities;
|
using Bit.SharedWeb.Utilities;
|
||||||
using Bit.Sso.IdentityServer;
|
using Bit.Sso.IdentityServer;
|
||||||
using Bit.Sso.Models;
|
using Bit.Sso.Models;
|
||||||
using IdentityServer4.Models;
|
using Duende.IdentityServer.Models;
|
||||||
using IdentityServer4.ResponseHandling;
|
using Duende.IdentityServer.ResponseHandling;
|
||||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||||
using Sustainsys.Saml2.AspNetCore2;
|
using Sustainsys.Saml2.AspNetCore2;
|
||||||
|
|
||||||
@ -59,6 +59,7 @@ public static class ServiceCollectionExtensions
|
|||||||
options.UserInteraction.ErrorIdParameter = "errorId";
|
options.UserInteraction.ErrorIdParameter = "errorId";
|
||||||
}
|
}
|
||||||
options.InputLengthRestrictions.UserName = 256;
|
options.InputLengthRestrictions.UserName = 256;
|
||||||
|
options.KeyManagement.Enabled = false;
|
||||||
})
|
})
|
||||||
.AddInMemoryCaching()
|
.AddInMemoryCaching()
|
||||||
.AddInMemoryClients(new List<Client>
|
.AddInMemoryClients(new List<Client>
|
||||||
|
@ -209,6 +209,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -245,49 +263,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -421,10 +398,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -457,8 +434,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Http.Abstractions": {
|
"Microsoft.AspNetCore.Http.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2777,10 +2754,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2808,7 +2784,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2816,7 +2792,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2828,9 +2804,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,6 +239,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fare": {
|
"Fare": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "2.1.1",
|
"resolved": "2.1.1",
|
||||||
@ -283,49 +301,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": {
|
"Kralizek.AutoFixture.Extensions.MockHttp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -412,10 +389,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -448,8 +425,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2680,7 +2657,7 @@
|
|||||||
"commercial.core": {
|
"commercial.core": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )"
|
"Core": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
@ -2688,7 +2665,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
||||||
"AutoFixture.Xunit2": "[4.17.0, )",
|
"AutoFixture.Xunit2": "[4.17.0, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
||||||
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
||||||
"NSubstitute": "[4.3.0, )",
|
"NSubstitute": "[4.3.0, )",
|
||||||
@ -2710,10 +2687,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2743,8 +2719,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
||||||
"AutoFixture.Xunit2": "[4.17.0, )",
|
"AutoFixture.Xunit2": "[4.17.0, )",
|
||||||
"Common": "[2023.10.2, )",
|
"Common": "[2023.10.3, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
||||||
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
||||||
"NSubstitute": "[4.3.0, )",
|
"NSubstitute": "[4.3.0, )",
|
||||||
|
@ -282,6 +282,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fare": {
|
"Fare": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "2.1.1",
|
"resolved": "2.1.1",
|
||||||
@ -326,49 +344,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": {
|
"Kralizek.AutoFixture.Extensions.MockHttp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -469,10 +446,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -505,8 +482,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.TestHost": {
|
"Microsoft.AspNetCore.TestHost": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2997,7 +2974,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
||||||
"AutoFixture.Xunit2": "[4.17.0, )",
|
"AutoFixture.Xunit2": "[4.17.0, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
||||||
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
||||||
"NSubstitute": "[4.3.0, )",
|
"NSubstitute": "[4.3.0, )",
|
||||||
@ -3019,10 +2996,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -3050,15 +3026,15 @@
|
|||||||
"identity": {
|
"identity": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"SharedWeb": "[2023.10.2, )",
|
"SharedWeb": "[2023.10.3, )",
|
||||||
"Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )"
|
"Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3066,7 +3042,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -3078,8 +3054,8 @@
|
|||||||
"integrationtestcommon": {
|
"integrationtestcommon": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Common": "[2023.10.2, )",
|
"Common": "[2023.10.3, )",
|
||||||
"Identity": "[2023.10.2, )",
|
"Identity": "[2023.10.3, )",
|
||||||
"Microsoft.AspNetCore.Mvc.Testing": "[6.0.5, )",
|
"Microsoft.AspNetCore.Mvc.Testing": "[6.0.5, )",
|
||||||
"Microsoft.Extensions.Configuration": "[6.0.1, )"
|
"Microsoft.Extensions.Configuration": "[6.0.1, )"
|
||||||
}
|
}
|
||||||
@ -3087,16 +3063,16 @@
|
|||||||
"scim": {
|
"scim": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"SharedWeb": "[2023.10.2, )"
|
"SharedWeb": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,6 +270,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fare": {
|
"Fare": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "2.1.1",
|
"resolved": "2.1.1",
|
||||||
@ -314,49 +332,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": {
|
"Kralizek.AutoFixture.Extensions.MockHttp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -457,10 +434,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -493,8 +470,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2850,7 +2827,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
"AutoFixture.AutoNSubstitute": "[4.17.0, )",
|
||||||
"AutoFixture.Xunit2": "[4.17.0, )",
|
"AutoFixture.Xunit2": "[4.17.0, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )",
|
||||||
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
"Microsoft.NET.Test.Sdk": "[17.1.0, )",
|
||||||
"NSubstitute": "[4.3.0, )",
|
"NSubstitute": "[4.3.0, )",
|
||||||
@ -2872,10 +2849,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2903,7 +2879,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2911,7 +2887,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2923,16 +2899,16 @@
|
|||||||
"scim": {
|
"scim": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"SharedWeb": "[2023.10.2, )"
|
"SharedWeb": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -233,49 +251,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -353,10 +330,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -389,8 +366,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2557,10 +2534,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
|
@ -82,7 +82,11 @@
|
|||||||
<label asp-for="PlanType"></label>
|
<label asp-for="PlanType"></label>
|
||||||
@{
|
@{
|
||||||
var planTypes = Enum.GetValues<PlanType>()
|
var planTypes = Enum.GetValues<PlanType>()
|
||||||
.Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.TeamsStarter)
|
.Where(p =>
|
||||||
|
Model.Provider == null ||
|
||||||
|
(Model.Provider != null
|
||||||
|
&& p is >= PlanType.TeamsMonthly2019 and <= PlanType.EnterpriseAnnually2019 or >= PlanType.TeamsMonthly2020 and <= PlanType.EnterpriseAnnually)
|
||||||
|
)
|
||||||
.Select(e => new SelectListItem
|
.Select(e => new SelectListItem
|
||||||
{
|
{
|
||||||
Value = ((int)e).ToString(),
|
Value = ((int)e).ToString(),
|
||||||
|
@ -223,6 +223,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -259,49 +277,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -393,10 +370,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -429,8 +406,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2808,15 +2785,15 @@
|
|||||||
"commercial.core": {
|
"commercial.core": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )"
|
"Core": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commercial.infrastructure.entityframework": {
|
"commercial.infrastructure.entityframework": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -2834,10 +2811,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2865,7 +2841,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2873,7 +2849,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2885,7 +2861,7 @@
|
|||||||
"migrator": {
|
"migrator": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.Extensions.Logging": "[6.0.0, )",
|
"Microsoft.Extensions.Logging": "[6.0.0, )",
|
||||||
"dbup-sqlserver": "[5.0.8, )"
|
"dbup-sqlserver": "[5.0.8, )"
|
||||||
}
|
}
|
||||||
@ -2893,30 +2869,30 @@
|
|||||||
"mysqlmigrations": {
|
"mysqlmigrations": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postgresmigrations": {
|
"postgresmigrations": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sqlitemigrations": {
|
"sqlitemigrations": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ using Bit.Api.Models.Response;
|
|||||||
using Bit.Api.Utilities;
|
using Bit.Api.Utilities;
|
||||||
using Bit.Api.Vault.AuthorizationHandlers.OrganizationUsers;
|
using Bit.Api.Vault.AuthorizationHandlers.OrganizationUsers;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
@ -12,7 +14,6 @@ using Bit.Core.Enums;
|
|||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
|
@ -11,6 +11,8 @@ using Bit.Api.Models.Request.Accounts;
|
|||||||
using Bit.Api.Models.Request.Organizations;
|
using Bit.Api.Models.Request.Organizations;
|
||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationApiKeys.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationApiKeys.Interfaces;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
@ -20,7 +22,6 @@ using Bit.Core.Context;
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces;
|
using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces;
|
||||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
@ -794,7 +795,7 @@ public class OrganizationsController : Controller
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _organizationService.UpdateAsync(model.ToOrganization(organization));
|
await _organizationService.UpdateAsync(model.ToOrganization(organization), eventType: EventType.Organization_CollectionManagement_Updated);
|
||||||
return new OrganizationResponseModel(organization);
|
return new OrganizationResponseModel(organization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
using Bit.Api.AdminConsole.Models.Request;
|
using Bit.Api.AdminConsole.Models.Request;
|
||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Api.Response;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Api.Response;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
|
||||||
namespace Bit.Api.AdminConsole.Models.Request;
|
namespace Bit.Api.AdminConsole.Models.Request;
|
||||||
|
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
using Bit.Api.AdminConsole.Public.Models.Request;
|
using Bit.Api.AdminConsole.Public.Models.Request;
|
||||||
using Bit.Api.AdminConsole.Public.Models.Response;
|
using Bit.Api.AdminConsole.Public.Models.Response;
|
||||||
using Bit.Api.Models.Public.Response;
|
using Bit.Api.Models.Public.Response;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
|
||||||
using Bit.Core.Repositories;
|
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
|
||||||
namespace Bit.Api.AdminConsole.Public.Models.Request;
|
namespace Bit.Api.AdminConsole.Public.Models.Request;
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Api.Models.Public.Response;
|
using Bit.Api.Models.Public.Response;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
|
||||||
namespace Bit.Api.AdminConsole.Public.Models.Response;
|
namespace Bit.Api.AdminConsole.Public.Models.Response;
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@ using Bit.Api.Auth.Models.Request;
|
|||||||
using Bit.Api.Auth.Models.Response;
|
using Bit.Api.Auth.Models.Response;
|
||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
using Bit.Api.Vault.Models.Response;
|
using Bit.Api.Vault.Models.Response;
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Models.Api.Response;
|
||||||
using Bit.Core.Auth.Services;
|
using Bit.Core.Auth.Services;
|
||||||
using Bit.Core.Entities;
|
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Api.Response;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
@ -3,9 +3,10 @@ using Bit.Api.Auth.Models.Request.Webauthn;
|
|||||||
using Bit.Api.Auth.Models.Response.WebAuthn;
|
using Bit.Api.Auth.Models.Response.WebAuthn;
|
||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
using Bit.Core.Enums;
|
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Tokens;
|
using Bit.Core.Tokens;
|
||||||
|
@ -7,6 +7,7 @@ using Bit.Api.Utilities;
|
|||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
using Bit.Core.AdminConsole.Enums.Provider;
|
using Bit.Core.AdminConsole.Enums.Provider;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Models.Api.Request.Accounts;
|
using Bit.Core.Auth.Models.Api.Request.Accounts;
|
||||||
using Bit.Core.Auth.Models.Api.Response.Accounts;
|
using Bit.Core.Auth.Models.Api.Response.Accounts;
|
||||||
using Bit.Core.Auth.Models.Data;
|
using Bit.Core.Auth.Models.Data;
|
||||||
|
@ -43,12 +43,12 @@ public class DomainsResponseModel : ResponseModel
|
|||||||
IEnumerable<GlobalEquivalentDomainsType> excludedDomains,
|
IEnumerable<GlobalEquivalentDomainsType> excludedDomains,
|
||||||
bool excluded)
|
bool excluded)
|
||||||
{
|
{
|
||||||
Type = globalDomain;
|
Type = (byte)globalDomain;
|
||||||
Domains = domains;
|
Domains = domains;
|
||||||
Excluded = excluded && (excludedDomains?.Contains(globalDomain) ?? false);
|
Excluded = excluded && (excludedDomains?.Contains(globalDomain) ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlobalEquivalentDomainsType Type { get; set; }
|
public byte Type { get; set; }
|
||||||
public IEnumerable<string> Domains { get; set; }
|
public IEnumerable<string> Domains { get; set; }
|
||||||
public bool Excluded { get; set; }
|
public bool Excluded { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ public class Program
|
|||||||
return e.Level >= globalSettings.MinLogLevel.ApiSettings.IpRateLimit;
|
return e.Level >= globalSettings.MinLogLevel.ApiSettings.IpRateLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") ||
|
||||||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator"))
|
||||||
{
|
{
|
||||||
return e.Level >= globalSettings.MinLogLevel.ApiSettings.IdentityToken;
|
return e.Level >= globalSettings.MinLogLevel.ApiSettings.IdentityToken;
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,12 @@ public class SMImportRequestModel
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[EncryptedString]
|
[EncryptedString]
|
||||||
[EncryptedStringLength(1000)]
|
[EncryptedStringLength(35000)]
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[EncryptedString]
|
[EncryptedString]
|
||||||
[EncryptedStringLength(1000)]
|
[EncryptedStringLength(10000)]
|
||||||
public string Note { get; set; }
|
public string Note { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core;
|
#nullable enable
|
||||||
|
using Bit.Core;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -19,6 +20,7 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
private readonly ICurrentContext _currentContext;
|
private readonly ICurrentContext _currentContext;
|
||||||
private readonly ICollectionRepository _collectionRepository;
|
private readonly ICollectionRepository _collectionRepository;
|
||||||
private readonly IFeatureService _featureService;
|
private readonly IFeatureService _featureService;
|
||||||
|
private Guid _targetOrganizationId;
|
||||||
|
|
||||||
private bool UseFlexibleCollections => _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections, _currentContext);
|
private bool UseFlexibleCollections => _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections, _currentContext);
|
||||||
|
|
||||||
@ -33,7 +35,7 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
|
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
|
||||||
CollectionOperationRequirement requirement, ICollection<Collection> resources)
|
CollectionOperationRequirement requirement, ICollection<Collection>? resources)
|
||||||
{
|
{
|
||||||
if (!UseFlexibleCollections)
|
if (!UseFlexibleCollections)
|
||||||
{
|
{
|
||||||
@ -41,6 +43,13 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
throw new FeatureUnavailableException("Flexible collections is OFF when it should be ON.");
|
throw new FeatureUnavailableException("Flexible collections is OFF when it should be ON.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Establish pattern of authorization handler null checking passed resources
|
||||||
|
if (resources == null || !resources.Any())
|
||||||
|
{
|
||||||
|
context.Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Acting user is not authenticated, fail
|
// Acting user is not authenticated, fail
|
||||||
if (!_currentContext.UserId.HasValue)
|
if (!_currentContext.UserId.HasValue)
|
||||||
{
|
{
|
||||||
@ -48,31 +57,15 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establish pattern of authorization handler null checking passed resources
|
_targetOrganizationId = resources.First().OrganizationId;
|
||||||
if (resources == null || !resources.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var targetOrganizationId = resources.FirstOrDefault()?.OrganizationId ?? default;
|
|
||||||
if (targetOrganizationId == default)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure all target collections belong to the same organization
|
// Ensure all target collections belong to the same organization
|
||||||
if (resources.Any(tc => tc.OrganizationId != targetOrganizationId))
|
if (resources.Any(tc => tc.OrganizationId != _targetOrganizationId))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("Requested collections must belong to the same organization.");
|
throw new BadRequestException("Requested collections must belong to the same organization.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acting user is not a member of the target organization, fail
|
var org = _currentContext.GetOrganization(_targetOrganizationId);
|
||||||
var org = _currentContext.GetOrganization(targetOrganizationId);
|
|
||||||
if (org == null)
|
|
||||||
{
|
|
||||||
context.Fail();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (requirement)
|
switch (requirement)
|
||||||
{
|
{
|
||||||
@ -97,20 +90,21 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task CanCreateAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
private async Task CanCreateAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
||||||
CurrentContextOrganization org)
|
CurrentContextOrganization? org)
|
||||||
{
|
{
|
||||||
// If false, all organization members are allowed to create collections
|
// If the limit collection management setting is disabled, allow any user to create collections
|
||||||
if (!org.LimitCollectionCreationDeletion)
|
// Otherwise, Owners, Admins, and users with CreateNewCollections permission can always create collections
|
||||||
|
if (org is
|
||||||
|
{ LimitCollectionCreationDeletion: false } or
|
||||||
|
{ Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or
|
||||||
|
{ Permissions.CreateNewCollections: true })
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Owners, Admins, Providers, and users with CreateNewCollections permission can always create collections
|
// Allow provider users to create collections if they are a provider for the target organization
|
||||||
if (
|
if (await _currentContext.ProviderUserForOrgAsync(_targetOrganizationId))
|
||||||
org.Type is OrganizationUserType.Owner or OrganizationUserType.Admin ||
|
|
||||||
org.Permissions is { CreateNewCollections: true } ||
|
|
||||||
await _currentContext.ProviderUserForOrgAsync(org.Id))
|
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
}
|
}
|
||||||
@ -135,27 +129,31 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task CanDeleteAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
private async Task CanDeleteAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
||||||
ICollection<Collection> targetCollections, CurrentContextOrganization org)
|
ICollection<Collection> resources, CurrentContextOrganization? org)
|
||||||
{
|
{
|
||||||
// Owners, Admins, Providers, and users with DeleteAnyCollection permission can always delete collections
|
// Owners, Admins, and users with DeleteAnyCollection permission can always delete collections
|
||||||
if (
|
if (org is
|
||||||
org.Type is OrganizationUserType.Owner or OrganizationUserType.Admin ||
|
{ Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or
|
||||||
org.Permissions is { DeleteAnyCollection: true } ||
|
{ Permissions.DeleteAnyCollection: true })
|
||||||
await _currentContext.ProviderUserForOrgAsync(org.Id))
|
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The limit collection management setting is enabled and we are not an Admin (above condition), fail
|
// The limit collection management setting is disabled,
|
||||||
if (org.LimitCollectionCreationDeletion)
|
// ensure acting user has manage permissions for all collections being deleted
|
||||||
|
if (org is { LimitCollectionCreationDeletion: false })
|
||||||
{
|
{
|
||||||
context.Fail();
|
var canManageCollections = await HasCollectionAccessAsync(resources, org, requireManagePermission: true);
|
||||||
|
if (canManageCollections)
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var canManageCollections = await HasCollectionAccessAsync(targetCollections, org, requireManagePermission: true);
|
// Allow providers to delete collections if they are a provider for the target organization
|
||||||
if (canManageCollections)
|
if (await _currentContext.ProviderUserForOrgAsync(_targetOrganizationId))
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
}
|
}
|
||||||
@ -165,20 +163,32 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<Colle
|
|||||||
/// Ensures the acting user is allowed to manage access permissions for the target collections.
|
/// Ensures the acting user is allowed to manage access permissions for the target collections.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task CanManageCollectionAccessAsync(AuthorizationHandlerContext context,
|
private async Task CanManageCollectionAccessAsync(AuthorizationHandlerContext context,
|
||||||
IAuthorizationRequirement requirement, ICollection<Collection> targetCollections, CurrentContextOrganization org)
|
IAuthorizationRequirement requirement, ICollection<Collection> resources,
|
||||||
|
CurrentContextOrganization? org)
|
||||||
{
|
{
|
||||||
// Owners, Admins, Providers, and users with EditAnyCollection permission can always manage collection access
|
// Owners, Admins, and users with EditAnyCollection permission can always manage collection access
|
||||||
if (
|
if (org is
|
||||||
org.Permissions is { EditAnyCollection: true } ||
|
{ Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or
|
||||||
org.Type is OrganizationUserType.Owner or OrganizationUserType.Admin ||
|
{ Permissions.EditAnyCollection: true })
|
||||||
await _currentContext.ProviderUserForOrgAsync(org.Id))
|
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var canManageCollections = await HasCollectionAccessAsync(targetCollections, org, requireManagePermission: true);
|
// The limit collection management setting is disabled,
|
||||||
|
// ensure acting user has manage permissions for all collections being deleted
|
||||||
|
if (org is { LimitCollectionCreationDeletion: false })
|
||||||
|
{
|
||||||
|
var canManageCollections = await HasCollectionAccessAsync(resources, org, requireManagePermission: true);
|
||||||
if (canManageCollections)
|
if (canManageCollections)
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow providers to manage collections if they are a provider for the target organization
|
||||||
|
if (await _currentContext.ProviderUserForOrgAsync(_targetOrganizationId))
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core;
|
#nullable enable
|
||||||
|
using Bit.Core;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
@ -15,6 +16,7 @@ public class CollectionAuthorizationHandler : AuthorizationHandler<CollectionOpe
|
|||||||
{
|
{
|
||||||
private readonly ICurrentContext _currentContext;
|
private readonly ICurrentContext _currentContext;
|
||||||
private readonly IFeatureService _featureService;
|
private readonly IFeatureService _featureService;
|
||||||
|
private Guid _targetOrganizationId;
|
||||||
|
|
||||||
private bool UseFlexibleCollections => _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections, _currentContext);
|
private bool UseFlexibleCollections => _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections, _currentContext);
|
||||||
|
|
||||||
@ -44,6 +46,7 @@ public class CollectionAuthorizationHandler : AuthorizationHandler<CollectionOpe
|
|||||||
|
|
||||||
if (requirement.OrganizationId == default)
|
if (requirement.OrganizationId == default)
|
||||||
{
|
{
|
||||||
|
context.Fail();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Api.Vault.Models.Response;
|
using Bit.Api.Vault.Models.Response;
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums.Provider;
|
using Bit.Core.AdminConsole.Enums.Provider;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
|
@ -18,6 +18,7 @@ public class CipherFido2CredentialModel
|
|||||||
RpId = data.RpId;
|
RpId = data.RpId;
|
||||||
RpName = data.RpName;
|
RpName = data.RpName;
|
||||||
UserHandle = data.UserHandle;
|
UserHandle = data.UserHandle;
|
||||||
|
UserName = data.UserName;
|
||||||
UserDisplayName = data.UserDisplayName;
|
UserDisplayName = data.UserDisplayName;
|
||||||
Counter = data.Counter;
|
Counter = data.Counter;
|
||||||
Discoverable = data.Discoverable;
|
Discoverable = data.Discoverable;
|
||||||
@ -50,6 +51,9 @@ public class CipherFido2CredentialModel
|
|||||||
public string UserHandle { get; set; }
|
public string UserHandle { get; set; }
|
||||||
[EncryptedString]
|
[EncryptedString]
|
||||||
[EncryptedStringLength(1000)]
|
[EncryptedStringLength(1000)]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
[EncryptedString]
|
||||||
|
[EncryptedStringLength(1000)]
|
||||||
public string UserDisplayName { get; set; }
|
public string UserDisplayName { get; set; }
|
||||||
[EncryptedString]
|
[EncryptedString]
|
||||||
[EncryptedStringLength(1000)]
|
[EncryptedStringLength(1000)]
|
||||||
@ -72,6 +76,7 @@ public class CipherFido2CredentialModel
|
|||||||
RpId = RpId,
|
RpId = RpId,
|
||||||
RpName = RpName,
|
RpName = RpName,
|
||||||
UserHandle = UserHandle,
|
UserHandle = UserHandle,
|
||||||
|
UserName = UserName,
|
||||||
UserDisplayName = UserDisplayName,
|
UserDisplayName = UserDisplayName,
|
||||||
Counter = Counter,
|
Counter = Counter,
|
||||||
Discoverable = Discoverable,
|
Discoverable = Discoverable,
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
using Bit.Api.Tools.Models.Response;
|
using Bit.Api.Tools.Models.Response;
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Models.Api.Response;
|
||||||
using Bit.Core.AdminConsole.Models.Data.Provider;
|
using Bit.Core.AdminConsole.Models.Data.Provider;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Bit.Core.Models.Api.Response;
|
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
@ -307,6 +307,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -343,49 +361,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -477,10 +454,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -513,8 +490,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2788,15 +2765,15 @@
|
|||||||
"commercial.core": {
|
"commercial.core": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )"
|
"Core": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commercial.infrastructure.entityframework": {
|
"commercial.infrastructure.entityframework": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -2814,10 +2791,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2845,7 +2821,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2853,7 +2829,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2865,9 +2841,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,9 +264,16 @@ public class StripeController : Controller
|
|||||||
|
|
||||||
await SendEmails(new List<string> { organization.BillingEmail });
|
await SendEmails(new List<string> { organization.BillingEmail });
|
||||||
|
|
||||||
var ownerEmails = await _organizationRepository.GetOwnerEmailAddressesById(organization.Id);
|
/*
|
||||||
|
* TODO: https://bitwarden.atlassian.net/browse/PM-4862
|
||||||
|
* Disabling this as part of a hot fix. It needs to check whether the organization
|
||||||
|
* belongs to a Reseller provider and only send an email to the organization owners if it does.
|
||||||
|
* It also requires a new email template as the current one contains too much billing information.
|
||||||
|
*/
|
||||||
|
|
||||||
await SendEmails(ownerEmails);
|
// var ownerEmails = await _organizationRepository.GetOwnerEmailAddressesById(organization.Id);
|
||||||
|
|
||||||
|
// await SendEmails(ownerEmails);
|
||||||
}
|
}
|
||||||
else if (userId.HasValue)
|
else if (userId.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +184,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -220,49 +238,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -354,10 +331,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -390,8 +367,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2617,10 +2594,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2648,7 +2624,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2656,7 +2632,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2668,9 +2644,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Entities;
|
namespace Bit.Core.AdminConsole.Entities;
|
||||||
|
|
||||||
public class Policy : ITableObject<Guid>
|
public class Policy : ITableObject<Guid>
|
||||||
{
|
{
|
@ -1,4 +1,4 @@
|
|||||||
namespace Bit.Core.Enums;
|
namespace Bit.Core.AdminConsole.Enums;
|
||||||
|
|
||||||
public enum PolicyType : byte
|
public enum PolicyType : byte
|
||||||
{
|
{
|
@ -1,8 +1,9 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.Models.Api;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Api.Response;
|
namespace Bit.Core.AdminConsole.Models.Api.Response;
|
||||||
|
|
||||||
public class PolicyResponseModel : ResponseModel
|
public class PolicyResponseModel : ResponseModel
|
||||||
{
|
{
|
@ -0,0 +1,5 @@
|
|||||||
|
namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
|
||||||
|
public interface IPolicyDataModel
|
||||||
|
{
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace Bit.Core.Models.Data.Organizations.Policies;
|
namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
|
||||||
public class MasterPasswordPolicyData : IPolicyDataModel
|
public class MasterPasswordPolicyData : IPolicyDataModel
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data.Organizations.Policies;
|
namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
|
||||||
public class ResetPasswordDataModel : IPolicyDataModel
|
public class ResetPasswordDataModel : IPolicyDataModel
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data.Organizations.Policies;
|
namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
|
||||||
public class SendOptionsPolicyData : IPolicyDataModel
|
public class SendOptionsPolicyData : IPolicyDataModel
|
||||||
{
|
{
|
@ -1,7 +1,8 @@
|
|||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
|
||||||
namespace Bit.Core.Repositories;
|
namespace Bit.Core.AdminConsole.Repositories;
|
||||||
|
|
||||||
public interface IPolicyRepository : IRepository<Policy, Guid>
|
public interface IPolicyRepository : IRepository<Policy, Guid>
|
||||||
{
|
{
|
@ -1,9 +1,12 @@
|
|||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
using Bit.Core.Services;
|
||||||
|
|
||||||
namespace Bit.Core.Services;
|
namespace Bit.Core.AdminConsole.Services;
|
||||||
|
|
||||||
public interface IPolicyService
|
public interface IPolicyService
|
||||||
{
|
{
|
@ -1,14 +1,18 @@
|
|||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
|
||||||
namespace Bit.Core.Services;
|
namespace Bit.Core.AdminConsole.Services.Implementations;
|
||||||
|
|
||||||
public class PolicyService : IPolicyService
|
public class PolicyService : IPolicyService
|
||||||
{
|
{
|
||||||
@ -114,12 +118,12 @@ public class PolicyService : IPolicyService
|
|||||||
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(
|
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(
|
||||||
policy.OrganizationId);
|
policy.OrganizationId);
|
||||||
var removableOrgUsers = orgUsers.Where(ou =>
|
var removableOrgUsers = orgUsers.Where(ou =>
|
||||||
ou.Status != Enums.OrganizationUserStatusType.Invited && ou.Status != Enums.OrganizationUserStatusType.Revoked &&
|
ou.Status != OrganizationUserStatusType.Invited && ou.Status != OrganizationUserStatusType.Revoked &&
|
||||||
ou.Type != Enums.OrganizationUserType.Owner && ou.Type != Enums.OrganizationUserType.Admin &&
|
ou.Type != OrganizationUserType.Owner && ou.Type != OrganizationUserType.Admin &&
|
||||||
ou.UserId != savingUserId);
|
ou.UserId != savingUserId);
|
||||||
switch (policy.Type)
|
switch (policy.Type)
|
||||||
{
|
{
|
||||||
case Enums.PolicyType.TwoFactorAuthentication:
|
case PolicyType.TwoFactorAuthentication:
|
||||||
foreach (var orgUser in removableOrgUsers)
|
foreach (var orgUser in removableOrgUsers)
|
||||||
{
|
{
|
||||||
if (!await userService.TwoFactorIsEnabledAsync(orgUser))
|
if (!await userService.TwoFactorIsEnabledAsync(orgUser))
|
||||||
@ -131,7 +135,7 @@ public class PolicyService : IPolicyService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Enums.PolicyType.SingleOrg:
|
case PolicyType.SingleOrg:
|
||||||
var userOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(
|
var userOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(
|
||||||
removableOrgUsers.Select(ou => ou.UserId.Value));
|
removableOrgUsers.Select(ou => ou.UserId.Value));
|
||||||
foreach (var orgUser in removableOrgUsers)
|
foreach (var orgUser in removableOrgUsers)
|
||||||
@ -154,7 +158,7 @@ public class PolicyService : IPolicyService
|
|||||||
}
|
}
|
||||||
policy.RevisionDate = now;
|
policy.RevisionDate = now;
|
||||||
await _policyRepository.UpsertAsync(policy);
|
await _policyRepository.UpsertAsync(policy);
|
||||||
await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Updated);
|
await _eventService.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user)
|
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user)
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace Bit.Core.Auth.Enums;
|
||||||
|
|
||||||
|
public enum WebAuthnLoginAssertionOptionsScope
|
||||||
|
{
|
||||||
|
Authentication = 0,
|
||||||
|
PrfRegistration = 1
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
using Bit.Core.Models.Api;
|
||||||
|
using Fido2NetLib;
|
||||||
|
|
||||||
|
namespace Bit.Core.Auth.Models.Api.Response.Accounts;
|
||||||
|
|
||||||
|
public class WebAuthnLoginAssertionOptionsResponseModel : ResponseModel
|
||||||
|
{
|
||||||
|
private const string ResponseObj = "webAuthnLoginAssertionOptions";
|
||||||
|
|
||||||
|
public WebAuthnLoginAssertionOptionsResponseModel() : base(ResponseObj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssertionOptions Options { get; set; }
|
||||||
|
public string Token { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,12 @@ public class UserDecryptionOptions : ResponseModel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasMasterPassword { get; set; }
|
public bool HasMasterPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the WebAuthn PRF decryption keys.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
public WebAuthnPrfDecryptionOption? WebAuthnPrfOption { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets information regarding this users trusted device decryption setup.
|
/// Gets or sets information regarding this users trusted device decryption setup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -29,6 +35,20 @@ public class UserDecryptionOptions : ResponseModel
|
|||||||
public KeyConnectorUserDecryptionOption? KeyConnectorOption { get; set; }
|
public KeyConnectorUserDecryptionOption? KeyConnectorOption { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class WebAuthnPrfDecryptionOption
|
||||||
|
{
|
||||||
|
public string EncryptedPrivateKey { get; }
|
||||||
|
public string EncryptedUserKey { get; }
|
||||||
|
|
||||||
|
public WebAuthnPrfDecryptionOption(
|
||||||
|
string encryptedPrivateKey,
|
||||||
|
string encryptedUserKey)
|
||||||
|
{
|
||||||
|
EncryptedPrivateKey = encryptedPrivateKey;
|
||||||
|
EncryptedUserKey = encryptedUserKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class TrustedDeviceUserDecryptionOption
|
public class TrustedDeviceUserDecryptionOption
|
||||||
{
|
{
|
||||||
public bool HasAdminApproval { get; }
|
public bool HasAdminApproval { get; }
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Bit.Core.Auth.Enums;
|
||||||
|
using Bit.Core.Tokens;
|
||||||
|
using Fido2NetLib;
|
||||||
|
|
||||||
|
namespace Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
|
|
||||||
|
public class WebAuthnLoginAssertionOptionsTokenable : ExpiringTokenable
|
||||||
|
{
|
||||||
|
// Lifetime 17 minutes =
|
||||||
|
// - 6 Minutes for Attestation (max webauthn timeout)
|
||||||
|
// - 6 Minutes for PRF Assertion (max webauthn timeout)
|
||||||
|
// - 5 minutes for user to complete the process (name their passkey, etc)
|
||||||
|
private static readonly TimeSpan _tokenLifetime = TimeSpan.FromMinutes(17);
|
||||||
|
public const string ClearTextPrefix = "BWWebAuthnLoginAssertionOptions_";
|
||||||
|
public const string DataProtectorPurpose = "WebAuthnLoginAssertionOptionsDataProtector";
|
||||||
|
public const string TokenIdentifier = "WebAuthnLoginAssertionOptionsToken";
|
||||||
|
|
||||||
|
public string Identifier { get; set; } = TokenIdentifier;
|
||||||
|
public AssertionOptions Options { get; set; }
|
||||||
|
public WebAuthnLoginAssertionOptionsScope Scope { get; set; }
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public WebAuthnLoginAssertionOptionsTokenable()
|
||||||
|
{
|
||||||
|
ExpirationDate = DateTime.UtcNow.Add(_tokenLifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WebAuthnLoginAssertionOptionsTokenable(WebAuthnLoginAssertionOptionsScope scope, AssertionOptions options) : this()
|
||||||
|
{
|
||||||
|
Scope = scope;
|
||||||
|
Options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TokenIsValid(WebAuthnLoginAssertionOptionsScope scope)
|
||||||
|
{
|
||||||
|
if (!Valid)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scope == scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TokenIsValid() => Identifier == TokenIdentifier && Options != null;
|
||||||
|
}
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
using Bit.Core.Entities;
|
|
||||||
using Bit.Core.Tokens;
|
|
||||||
|
|
||||||
namespace Bit.Core.Auth.Models.Business.Tokenables;
|
|
||||||
|
|
||||||
public class WebAuthnLoginTokenable : ExpiringTokenable
|
|
||||||
{
|
|
||||||
private const double _tokenLifetimeInHours = (double)1 / 60; // 1 minute
|
|
||||||
public const string ClearTextPrefix = "BWWebAuthnLogin_";
|
|
||||||
public const string DataProtectorPurpose = "WebAuthnLoginDataProtector";
|
|
||||||
public const string TokenIdentifier = "WebAuthnLoginToken";
|
|
||||||
|
|
||||||
public string Identifier { get; set; } = TokenIdentifier;
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string Email { get; set; }
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
public WebAuthnLoginTokenable()
|
|
||||||
{
|
|
||||||
ExpirationDate = DateTime.UtcNow.AddHours(_tokenLifetimeInHours);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebAuthnLoginTokenable(User user) : this()
|
|
||||||
{
|
|
||||||
Id = user?.Id ?? default;
|
|
||||||
Email = user?.Email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TokenIsValid(User user)
|
|
||||||
{
|
|
||||||
if (Id == default || Email == default || user == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Id == user.Id &&
|
|
||||||
Email.Equals(user.Email, StringComparison.InvariantCultureIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validates deserialized
|
|
||||||
protected override bool TokenIsValid() => Identifier == TokenIdentifier && Id != default && !string.IsNullOrWhiteSpace(Email);
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models.Data;
|
using Bit.Core.Auth.Models.Data;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models;
|
using Bit.Core.Auth.Models;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
|
|
||||||
|
19
src/Core/Auth/Utilities/GuidUtilities.cs
Normal file
19
src/Core/Auth/Utilities/GuidUtilities.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
namespace Bit.Core.Auth.Utilities;
|
||||||
|
|
||||||
|
public static class GuidUtilities
|
||||||
|
{
|
||||||
|
public static bool TryParseBytes(ReadOnlySpan<byte> bytes, out Guid guid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
guid = new Guid(bytes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
guid = Guid.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,18 +26,9 @@ public static class Constants
|
|||||||
public const string CipherKeyEncryptionMinimumVersion = "2023.9.2";
|
public const string CipherKeyEncryptionMinimumVersion = "2023.9.2";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When you set the ProrationBehavior to create_prorations,
|
/// Used by IdentityServer to identify our own provider.
|
||||||
/// Stripe will automatically create prorations for any changes made to the subscription,
|
|
||||||
/// such as changing the plan, adding or removing quantities, or applying discounts.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CreateProrations = "create_prorations";
|
public const string IdentityProvider = "bitwarden";
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// When you set the ProrationBehavior to always_invoice,
|
|
||||||
/// Stripe will always generate an invoice when a subscription update occurs,
|
|
||||||
/// regardless of whether there is a proration or not.
|
|
||||||
/// </summary>
|
|
||||||
public const string AlwaysInvoice = "always_invoice";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TokenPurposes
|
public static class TokenPurposes
|
||||||
@ -57,6 +48,7 @@ public static class FeatureFlagKeys
|
|||||||
public const string PasswordlessLogin = "passwordless-login";
|
public const string PasswordlessLogin = "passwordless-login";
|
||||||
public const string TrustedDeviceEncryption = "trusted-device-encryption";
|
public const string TrustedDeviceEncryption = "trusted-device-encryption";
|
||||||
public const string Fido2VaultCredentials = "fido2-vault-credentials";
|
public const string Fido2VaultCredentials = "fido2-vault-credentials";
|
||||||
|
public const string VaultOnboarding = "vault-onboarding";
|
||||||
public const string AutofillV2 = "autofill-v2";
|
public const string AutofillV2 = "autofill-v2";
|
||||||
public const string BrowserFilelessImport = "browser-fileless-import";
|
public const string BrowserFilelessImport = "browser-fileless-import";
|
||||||
public const string FlexibleCollections = "flexible-collections";
|
public const string FlexibleCollections = "flexible-collections";
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
<PackageReference Include="DnsClient" Version="1.7.0" />
|
<PackageReference Include="DnsClient" Version="1.7.0" />
|
||||||
<PackageReference Include="Fido2.AspNet" Version="3.0.1" />
|
<PackageReference Include="Fido2.AspNet" Version="3.0.1" />
|
||||||
<PackageReference Include="Handlebars.Net" Version="2.1.2" />
|
<PackageReference Include="Handlebars.Net" Version="2.1.2" />
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
|
||||||
<PackageReference Include="MailKit" Version="4.2.0" />
|
<PackageReference Include="MailKit" Version="4.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.4" />
|
||||||
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.8" />
|
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.8" />
|
||||||
@ -48,7 +47,7 @@
|
|||||||
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
|
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
|
||||||
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
|
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
|
||||||
<PackageReference Include="Sentry.Serilog" Version="3.16.0" />
|
<PackageReference Include="Sentry.Serilog" Version="3.16.0" />
|
||||||
<PackageReference Include="IdentityServer4" Version="4.1.2" />
|
<PackageReference Include="Duende.IdentityServer" Version="6.0.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.AzureCosmosDB" Version="2.0.0" />
|
<PackageReference Include="Serilog.Sinks.AzureCosmosDB" Version="2.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="2.0.6" />
|
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="2.0.6" />
|
||||||
|
@ -67,6 +67,7 @@ public enum EventType : int
|
|||||||
Organization_EnabledKeyConnector = 1606,
|
Organization_EnabledKeyConnector = 1606,
|
||||||
Organization_DisabledKeyConnector = 1607,
|
Organization_DisabledKeyConnector = 1607,
|
||||||
Organization_SponsorshipsSynced = 1608,
|
Organization_SponsorshipsSynced = 1608,
|
||||||
|
Organization_CollectionManagement_Updated = 1609,
|
||||||
|
|
||||||
Policy_Updated = 1700,
|
Policy_Updated = 1700,
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using IdentityServer4.Models;
|
using Duende.IdentityServer.Models;
|
||||||
|
|
||||||
namespace Bit.Core.IdentityServer;
|
namespace Bit.Core.IdentityServer;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using IdentityServer4.Configuration;
|
using Duende.IdentityServer.Configuration;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Caching.StackExchangeRedis;
|
using Microsoft.Extensions.Caching.StackExchangeRedis;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Api.Response;
|
namespace Bit.Core.Models.Api.Response;
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
namespace Bit.Core.Models.Business;
|
|
||||||
|
|
||||||
public class InvoicePreviewResult
|
|
||||||
{
|
|
||||||
public bool IsInvoicedNow { get; set; }
|
|
||||||
public string PaymentIntentClientSecret { get; set; }
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
using Stripe;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Business;
|
|
||||||
|
|
||||||
public class PendingInoviceItems
|
|
||||||
{
|
|
||||||
public IEnumerable<InvoiceItem> PendingInvoiceItems { get; set; }
|
|
||||||
public IDictionary<string, InvoiceItem> PendingInvoiceItemsDict { get; set; }
|
|
||||||
}
|
|
@ -44,7 +44,7 @@ public class SecretsManagerSubscribeUpdate : SubscriptionUpdate
|
|||||||
{
|
{
|
||||||
updatedItems.Add(new SubscriptionItemOptions
|
updatedItems.Add(new SubscriptionItemOptions
|
||||||
{
|
{
|
||||||
Plan = _plan.SecretsManager.StripeSeatPlanId,
|
Price = _plan.SecretsManager.StripeSeatPlanId,
|
||||||
Quantity = _additionalSeats
|
Quantity = _additionalSeats
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ public class SecretsManagerSubscribeUpdate : SubscriptionUpdate
|
|||||||
{
|
{
|
||||||
updatedItems.Add(new SubscriptionItemOptions
|
updatedItems.Add(new SubscriptionItemOptions
|
||||||
{
|
{
|
||||||
Plan = _plan.SecretsManager.StripeServiceAccountPlanId,
|
Price = _plan.SecretsManager.StripeServiceAccountPlanId,
|
||||||
Quantity = _additionalServiceAccounts
|
Quantity = _additionalServiceAccounts
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -63,14 +63,14 @@ public class SecretsManagerSubscribeUpdate : SubscriptionUpdate
|
|||||||
{
|
{
|
||||||
updatedItems.Add(new SubscriptionItemOptions
|
updatedItems.Add(new SubscriptionItemOptions
|
||||||
{
|
{
|
||||||
Plan = _plan.SecretsManager.StripeSeatPlanId,
|
Price = _plan.SecretsManager.StripeSeatPlanId,
|
||||||
Quantity = _previousSeats,
|
Quantity = _previousSeats,
|
||||||
Deleted = _previousSeats == 0 ? true : (bool?)null,
|
Deleted = _previousSeats == 0 ? true : (bool?)null,
|
||||||
});
|
});
|
||||||
|
|
||||||
updatedItems.Add(new SubscriptionItemOptions
|
updatedItems.Add(new SubscriptionItemOptions
|
||||||
{
|
{
|
||||||
Plan = _plan.SecretsManager.StripeServiceAccountPlanId,
|
Price = _plan.SecretsManager.StripeServiceAccountPlanId,
|
||||||
Quantity = _previousServiceAccounts,
|
Quantity = _previousServiceAccounts,
|
||||||
Deleted = _previousServiceAccounts == 0 ? true : (bool?)null,
|
Deleted = _previousServiceAccounts == 0 ? true : (bool?)null,
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
namespace Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
namespace Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
|
|
||||||
public interface IPolicyDataModel
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Entities;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
|
@ -27,7 +27,7 @@ public interface IOrganizationService
|
|||||||
Task DisableAsync(Guid organizationId, DateTime? expirationDate);
|
Task DisableAsync(Guid organizationId, DateTime? expirationDate);
|
||||||
Task UpdateExpirationDateAsync(Guid organizationId, DateTime? expirationDate);
|
Task UpdateExpirationDateAsync(Guid organizationId, DateTime? expirationDate);
|
||||||
Task EnableAsync(Guid organizationId);
|
Task EnableAsync(Guid organizationId);
|
||||||
Task UpdateAsync(Organization organization, bool updateBilling = false);
|
Task UpdateAsync(Organization organization, bool updateBilling = false, EventType eventType = EventType.Organization_Updated);
|
||||||
Task UpdateTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type);
|
Task UpdateTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type);
|
||||||
Task DisableTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type);
|
Task DisableTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type);
|
||||||
Task<List<OrganizationUser>> InviteUsersAsync(Guid organizationId, Guid? invitingUserId,
|
Task<List<OrganizationUser>> InviteUsersAsync(Guid organizationId, Guid? invitingUserId,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Models.BitStripe;
|
using Bit.Core.Models.BitStripe;
|
||||||
using Stripe;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services;
|
namespace Bit.Core.Services;
|
||||||
|
|
||||||
@ -15,11 +14,8 @@ public interface IStripeAdapter
|
|||||||
Task<Stripe.Subscription> SubscriptionUpdateAsync(string id, Stripe.SubscriptionUpdateOptions options = null);
|
Task<Stripe.Subscription> SubscriptionUpdateAsync(string id, Stripe.SubscriptionUpdateOptions options = null);
|
||||||
Task<Stripe.Subscription> SubscriptionCancelAsync(string Id, Stripe.SubscriptionCancelOptions options = null);
|
Task<Stripe.Subscription> SubscriptionCancelAsync(string Id, Stripe.SubscriptionCancelOptions options = null);
|
||||||
Task<Stripe.Invoice> InvoiceUpcomingAsync(Stripe.UpcomingInvoiceOptions options);
|
Task<Stripe.Invoice> InvoiceUpcomingAsync(Stripe.UpcomingInvoiceOptions options);
|
||||||
Task<Stripe.Invoice> InvoiceCreateAsync(Stripe.InvoiceCreateOptions options);
|
|
||||||
Task<Stripe.InvoiceItem> InvoiceItemCreateAsync(Stripe.InvoiceItemCreateOptions options);
|
|
||||||
Task<Stripe.Invoice> InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options);
|
Task<Stripe.Invoice> InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options);
|
||||||
Task<List<Stripe.Invoice>> InvoiceListAsync(StripeInvoiceListOptions options);
|
Task<List<Stripe.Invoice>> InvoiceListAsync(StripeInvoiceListOptions options);
|
||||||
IEnumerable<InvoiceItem> InvoiceItemListAsync(InvoiceItemListOptions options);
|
|
||||||
Task<Stripe.Invoice> InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options);
|
Task<Stripe.Invoice> InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options);
|
||||||
Task<Stripe.Invoice> InvoiceFinalizeInvoiceAsync(string id, Stripe.InvoiceFinalizeOptions options);
|
Task<Stripe.Invoice> InvoiceFinalizeInvoiceAsync(string id, Stripe.InvoiceFinalizeOptions options);
|
||||||
Task<Stripe.Invoice> InvoiceSendInvoiceAsync(string id, Stripe.InvoiceSendOptions options);
|
Task<Stripe.Invoice> InvoiceSendInvoiceAsync(string id, Stripe.InvoiceSendOptions options);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models;
|
using Bit.Core.Auth.Models;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
@ -29,8 +30,8 @@ public interface IUserService
|
|||||||
Task<bool> CompleteWebAuthRegistrationAsync(User user, int value, string name, AuthenticatorAttestationRawResponse attestationResponse);
|
Task<bool> CompleteWebAuthRegistrationAsync(User user, int value, string name, AuthenticatorAttestationRawResponse attestationResponse);
|
||||||
Task<CredentialCreateOptions> StartWebAuthnLoginRegistrationAsync(User user);
|
Task<CredentialCreateOptions> StartWebAuthnLoginRegistrationAsync(User user);
|
||||||
Task<bool> CompleteWebAuthLoginRegistrationAsync(User user, string name, CredentialCreateOptions options, AuthenticatorAttestationRawResponse attestationResponse, bool supportsPrf, string encryptedUserKey = null, string encryptedPublicKey = null, string encryptedPrivateKey = null);
|
Task<bool> CompleteWebAuthLoginRegistrationAsync(User user, string name, CredentialCreateOptions options, AuthenticatorAttestationRawResponse attestationResponse, bool supportsPrf, string encryptedUserKey = null, string encryptedPublicKey = null, string encryptedPrivateKey = null);
|
||||||
Task<AssertionOptions> StartWebAuthnLoginAssertionAsync(User user);
|
AssertionOptions StartWebAuthnLoginAssertion();
|
||||||
Task<string> CompleteWebAuthLoginAssertionAsync(AuthenticatorAssertionRawResponse assertionResponse, User user);
|
Task<(User, WebAuthnCredential)> CompleteWebAuthLoginAssertionAsync(AssertionOptions options, AuthenticatorAssertionRawResponse assertionResponse);
|
||||||
Task SendEmailVerificationAsync(User user);
|
Task SendEmailVerificationAsync(User user);
|
||||||
Task<IdentityResult> ConfirmEmailAsync(User user, string token);
|
Task<IdentityResult> ConfirmEmailAsync(User user, string token);
|
||||||
Task InitiateEmailChangeAsync(User user, string newEmail);
|
Task InitiateEmailChangeAsync(User user, string newEmail);
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
using Bit.Core.AdminConsole.Enums.Provider;
|
using Bit.Core.AdminConsole.Enums.Provider;
|
||||||
using Bit.Core.AdminConsole.Models.Business;
|
using Bit.Core.AdminConsole.Models.Business;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models.Business;
|
using Bit.Core.Auth.Models.Business;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
@ -15,7 +18,6 @@ using Bit.Core.Enums;
|
|||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
@ -57,6 +59,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
private readonly IProviderUserRepository _providerUserRepository;
|
private readonly IProviderUserRepository _providerUserRepository;
|
||||||
private readonly ICountNewSmSeatsRequiredQuery _countNewSmSeatsRequiredQuery;
|
private readonly ICountNewSmSeatsRequiredQuery _countNewSmSeatsRequiredQuery;
|
||||||
private readonly IUpdateSecretsManagerSubscriptionCommand _updateSecretsManagerSubscriptionCommand;
|
private readonly IUpdateSecretsManagerSubscriptionCommand _updateSecretsManagerSubscriptionCommand;
|
||||||
|
private readonly IProviderRepository _providerRepository;
|
||||||
private readonly IOrgUserInviteTokenableFactory _orgUserInviteTokenableFactory;
|
private readonly IOrgUserInviteTokenableFactory _orgUserInviteTokenableFactory;
|
||||||
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory;
|
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory;
|
||||||
private readonly IFeatureService _featureService;
|
private readonly IFeatureService _featureService;
|
||||||
@ -90,6 +93,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
IOrgUserInviteTokenableFactory orgUserInviteTokenableFactory,
|
IOrgUserInviteTokenableFactory orgUserInviteTokenableFactory,
|
||||||
IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory,
|
IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory,
|
||||||
IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand,
|
IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand,
|
||||||
|
IProviderRepository providerRepository,
|
||||||
IFeatureService featureService)
|
IFeatureService featureService)
|
||||||
{
|
{
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
@ -118,6 +122,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
_providerUserRepository = providerUserRepository;
|
_providerUserRepository = providerUserRepository;
|
||||||
_countNewSmSeatsRequiredQuery = countNewSmSeatsRequiredQuery;
|
_countNewSmSeatsRequiredQuery = countNewSmSeatsRequiredQuery;
|
||||||
_updateSecretsManagerSubscriptionCommand = updateSecretsManagerSubscriptionCommand;
|
_updateSecretsManagerSubscriptionCommand = updateSecretsManagerSubscriptionCommand;
|
||||||
|
_providerRepository = providerRepository;
|
||||||
_orgUserInviteTokenableFactory = orgUserInviteTokenableFactory;
|
_orgUserInviteTokenableFactory = orgUserInviteTokenableFactory;
|
||||||
_orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory;
|
_orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory;
|
||||||
_featureService = featureService;
|
_featureService = featureService;
|
||||||
@ -736,7 +741,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateAsync(Organization organization, bool updateBilling = false)
|
public async Task UpdateAsync(Organization organization, bool updateBilling = false, EventType eventType = EventType.Organization_Updated)
|
||||||
{
|
{
|
||||||
if (organization.Id == default(Guid))
|
if (organization.Id == default(Guid))
|
||||||
{
|
{
|
||||||
@ -752,7 +757,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await ReplaceAndUpdateCacheAsync(organization, EventType.Organization_Updated);
|
await ReplaceAndUpdateCacheAsync(organization, eventType);
|
||||||
|
|
||||||
if (updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
if (updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
@ -862,7 +867,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
|
|
||||||
if (newSeatsRequired > 0)
|
if (newSeatsRequired > 0)
|
||||||
{
|
{
|
||||||
var (canScale, failureReason) = CanScale(organization, newSeatsRequired);
|
var (canScale, failureReason) = await CanScaleAsync(organization, newSeatsRequired);
|
||||||
if (!canScale)
|
if (!canScale)
|
||||||
{
|
{
|
||||||
throw new BadRequestException(failureReason);
|
throw new BadRequestException(failureReason);
|
||||||
@ -1182,7 +1187,8 @@ public class OrganizationService : IOrganizationService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal (bool canScale, string failureReason) CanScale(Organization organization,
|
internal async Task<(bool canScale, string failureReason)> CanScaleAsync(
|
||||||
|
Organization organization,
|
||||||
int seatsToAdd)
|
int seatsToAdd)
|
||||||
{
|
{
|
||||||
var failureReason = "";
|
var failureReason = "";
|
||||||
@ -1197,6 +1203,13 @@ public class OrganizationService : IOrganizationService
|
|||||||
return (true, failureReason);
|
return (true, failureReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var provider = await _providerRepository.GetByOrganizationIdAsync(organization.Id);
|
||||||
|
|
||||||
|
if (provider is { Enabled: true, Type: ProviderType.Reseller })
|
||||||
|
{
|
||||||
|
return (false, "Seat limit has been reached. Contact your provider to purchase additional seats.");
|
||||||
|
}
|
||||||
|
|
||||||
if (organization.Seats.HasValue &&
|
if (organization.Seats.HasValue &&
|
||||||
organization.MaxAutoscaleSeats.HasValue &&
|
organization.MaxAutoscaleSeats.HasValue &&
|
||||||
organization.MaxAutoscaleSeats.Value < organization.Seats.Value + seatsToAdd)
|
organization.MaxAutoscaleSeats.Value < organization.Seats.Value + seatsToAdd)
|
||||||
@ -1214,7 +1227,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (canScale, failureMessage) = CanScale(organization, seatsToAdd);
|
var (canScale, failureMessage) = await CanScaleAsync(organization, seatsToAdd);
|
||||||
if (!canScale)
|
if (!canScale)
|
||||||
{
|
{
|
||||||
throw new BadRequestException(failureMessage);
|
throw new BadRequestException(failureMessage);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Models.BitStripe;
|
using Bit.Core.Models.BitStripe;
|
||||||
using Stripe;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services;
|
namespace Bit.Core.Services;
|
||||||
|
|
||||||
@ -17,7 +16,6 @@ public class StripeAdapter : IStripeAdapter
|
|||||||
private readonly Stripe.BankAccountService _bankAccountService;
|
private readonly Stripe.BankAccountService _bankAccountService;
|
||||||
private readonly Stripe.PriceService _priceService;
|
private readonly Stripe.PriceService _priceService;
|
||||||
private readonly Stripe.TestHelpers.TestClockService _testClockService;
|
private readonly Stripe.TestHelpers.TestClockService _testClockService;
|
||||||
private readonly Stripe.InvoiceItemService _invoiceItemService;
|
|
||||||
|
|
||||||
public StripeAdapter()
|
public StripeAdapter()
|
||||||
{
|
{
|
||||||
@ -33,7 +31,6 @@ public class StripeAdapter : IStripeAdapter
|
|||||||
_bankAccountService = new Stripe.BankAccountService();
|
_bankAccountService = new Stripe.BankAccountService();
|
||||||
_priceService = new Stripe.PriceService();
|
_priceService = new Stripe.PriceService();
|
||||||
_testClockService = new Stripe.TestHelpers.TestClockService();
|
_testClockService = new Stripe.TestHelpers.TestClockService();
|
||||||
_invoiceItemService = new Stripe.InvoiceItemService();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Stripe.Customer> CustomerCreateAsync(Stripe.CustomerCreateOptions options)
|
public Task<Stripe.Customer> CustomerCreateAsync(Stripe.CustomerCreateOptions options)
|
||||||
@ -82,16 +79,6 @@ public class StripeAdapter : IStripeAdapter
|
|||||||
return _invoiceService.UpcomingAsync(options);
|
return _invoiceService.UpcomingAsync(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Stripe.Invoice> InvoiceCreateAsync(Stripe.InvoiceCreateOptions options)
|
|
||||||
{
|
|
||||||
return _invoiceService.CreateAsync(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Stripe.InvoiceItem> InvoiceItemCreateAsync(Stripe.InvoiceItemCreateOptions options)
|
|
||||||
{
|
|
||||||
return _invoiceItemService.CreateAsync(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Stripe.Invoice> InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options)
|
public Task<Stripe.Invoice> InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options)
|
||||||
{
|
{
|
||||||
return _invoiceService.GetAsync(id, options);
|
return _invoiceService.GetAsync(id, options);
|
||||||
@ -116,11 +103,6 @@ public class StripeAdapter : IStripeAdapter
|
|||||||
return invoices;
|
return invoices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<InvoiceItem> InvoiceItemListAsync(InvoiceItemListOptions options)
|
|
||||||
{
|
|
||||||
return _invoiceItemService.ListAutoPaging(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Stripe.Invoice> InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options)
|
public Task<Stripe.Invoice> InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options)
|
||||||
{
|
{
|
||||||
return _invoiceService.UpdateAsync(id, options);
|
return _invoiceService.UpdateAsync(id, options);
|
||||||
|
@ -7,7 +7,6 @@ using Bit.Core.Models.Business;
|
|||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Stripe;
|
|
||||||
using StaticStore = Bit.Core.Models.StaticStore;
|
using StaticStore = Bit.Core.Models.StaticStore;
|
||||||
using TaxRate = Bit.Core.Entities.TaxRate;
|
using TaxRate = Bit.Core.Entities.TaxRate;
|
||||||
|
|
||||||
@ -751,14 +750,16 @@ public class StripePaymentService : IPaymentService
|
|||||||
prorationDate ??= DateTime.UtcNow;
|
prorationDate ??= DateTime.UtcNow;
|
||||||
var collectionMethod = sub.CollectionMethod;
|
var collectionMethod = sub.CollectionMethod;
|
||||||
var daysUntilDue = sub.DaysUntilDue;
|
var daysUntilDue = sub.DaysUntilDue;
|
||||||
|
var chargeNow = collectionMethod == "charge_automatically";
|
||||||
var updatedItemOptions = subscriptionUpdate.UpgradeItemsOptions(sub);
|
var updatedItemOptions = subscriptionUpdate.UpgradeItemsOptions(sub);
|
||||||
|
|
||||||
var subUpdateOptions = new Stripe.SubscriptionUpdateOptions
|
var subUpdateOptions = new Stripe.SubscriptionUpdateOptions
|
||||||
{
|
{
|
||||||
Items = updatedItemOptions,
|
Items = updatedItemOptions,
|
||||||
ProrationBehavior = Constants.CreateProrations,
|
ProrationBehavior = "always_invoice",
|
||||||
DaysUntilDue = daysUntilDue ?? 1,
|
DaysUntilDue = daysUntilDue ?? 1,
|
||||||
CollectionMethod = "send_invoice"
|
CollectionMethod = "send_invoice",
|
||||||
|
ProrationDate = prorationDate,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!subscriptionUpdate.UpdateNeeded(sub))
|
if (!subscriptionUpdate.UpdateNeeded(sub))
|
||||||
@ -792,26 +793,34 @@ public class StripePaymentService : IPaymentService
|
|||||||
string paymentIntentClientSecret = null;
|
string paymentIntentClientSecret = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var subItemOptions = updatedItemOptions.Select(itemOption =>
|
|
||||||
new Stripe.InvoiceSubscriptionItemOptions
|
|
||||||
{
|
|
||||||
Id = itemOption.Id,
|
|
||||||
Plan = itemOption.Plan,
|
|
||||||
Quantity = itemOption.Quantity,
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
var reviewInvoiceResponse = await PreviewUpcomingInvoiceAndPayAsync(storableSubscriber, subItemOptions);
|
|
||||||
paymentIntentClientSecret = reviewInvoiceResponse.PaymentIntentClientSecret;
|
|
||||||
|
|
||||||
var subResponse = await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, subUpdateOptions);
|
var subResponse = await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, subUpdateOptions);
|
||||||
var invoice =
|
|
||||||
await _stripeAdapter.InvoiceGetAsync(subResponse?.LatestInvoiceId, new Stripe.InvoiceGetOptions());
|
var invoice = await _stripeAdapter.InvoiceGetAsync(subResponse?.LatestInvoiceId, new Stripe.InvoiceGetOptions());
|
||||||
if (invoice == null)
|
if (invoice == null)
|
||||||
{
|
{
|
||||||
throw new BadRequestException("Unable to locate draft invoice for subscription update.");
|
throw new BadRequestException("Unable to locate draft invoice for subscription update.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (invoice.AmountDue > 0 && updatedItemOptions.Any(i => i.Quantity > 0))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (chargeNow)
|
||||||
|
{
|
||||||
|
paymentIntentClientSecret = await PayInvoiceAfterSubscriptionChangeAsync(
|
||||||
|
storableSubscriber, invoice);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
else
|
||||||
|
{
|
||||||
|
invoice = await _stripeAdapter.InvoiceFinalizeInvoiceAsync(subResponse.LatestInvoiceId, new Stripe.InvoiceFinalizeOptions
|
||||||
|
{
|
||||||
|
AutoAdvance = false,
|
||||||
|
});
|
||||||
|
await _stripeAdapter.InvoiceSendInvoiceAsync(invoice.Id, new Stripe.InvoiceSendOptions());
|
||||||
|
paymentIntentClientSecret = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
{
|
{
|
||||||
// Need to revert the subscription
|
// Need to revert the subscription
|
||||||
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new Stripe.SubscriptionUpdateOptions
|
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new Stripe.SubscriptionUpdateOptions
|
||||||
@ -825,13 +834,21 @@ public class StripePaymentService : IPaymentService
|
|||||||
});
|
});
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (!invoice.Paid)
|
||||||
|
{
|
||||||
|
// Pay invoice with no charge to customer this completes the invoice immediately without waiting the scheduled 1h
|
||||||
|
invoice = await _stripeAdapter.InvoicePayAsync(subResponse.LatestInvoiceId);
|
||||||
|
paymentIntentClientSecret = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Change back the subscription collection method and/or days until due
|
// Change back the subscription collection method and/or days until due
|
||||||
if (collectionMethod != "send_invoice" || daysUntilDue == null)
|
if (collectionMethod != "send_invoice" || daysUntilDue == null)
|
||||||
{
|
{
|
||||||
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id,
|
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new Stripe.SubscriptionUpdateOptions
|
||||||
new Stripe.SubscriptionUpdateOptions
|
|
||||||
{
|
{
|
||||||
CollectionMethod = collectionMethod,
|
CollectionMethod = collectionMethod,
|
||||||
DaysUntilDue = daysUntilDue,
|
DaysUntilDue = daysUntilDue,
|
||||||
@ -918,7 +935,6 @@ public class StripePaymentService : IPaymentService
|
|||||||
await _stripeAdapter.CustomerDeleteAsync(subscriber.GatewayCustomerId);
|
await _stripeAdapter.CustomerDeleteAsync(subscriber.GatewayCustomerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//This method is no-longer is use because we return the dollar threshold feature on invoice will be generated. but we dont want to lose this implementation.
|
|
||||||
public async Task<string> PayInvoiceAfterSubscriptionChangeAsync(ISubscriber subscriber, Stripe.Invoice invoice)
|
public async Task<string> PayInvoiceAfterSubscriptionChangeAsync(ISubscriber subscriber, Stripe.Invoice invoice)
|
||||||
{
|
{
|
||||||
var customerOptions = new Stripe.CustomerGetOptions();
|
var customerOptions = new Stripe.CustomerGetOptions();
|
||||||
@ -1088,310 +1104,6 @@ public class StripePaymentService : IPaymentService
|
|||||||
return paymentIntentClientSecret;
|
return paymentIntentClientSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<InvoicePreviewResult> PreviewUpcomingInvoiceAndPayAsync(ISubscriber subscriber,
|
|
||||||
List<Stripe.InvoiceSubscriptionItemOptions> subItemOptions, int prorateThreshold = 50000)
|
|
||||||
{
|
|
||||||
var customer = await CheckInAppPurchaseMethod(subscriber);
|
|
||||||
|
|
||||||
string paymentIntentClientSecret = null;
|
|
||||||
|
|
||||||
var pendingInvoiceItems = GetPendingInvoiceItems(subscriber);
|
|
||||||
|
|
||||||
var upcomingPreview = await GetUpcomingInvoiceAsync(subscriber, subItemOptions);
|
|
||||||
|
|
||||||
var itemsForInvoice = GetItemsForInvoice(subItemOptions, upcomingPreview, pendingInvoiceItems);
|
|
||||||
var invoiceAmount = itemsForInvoice?.Sum(i => i.Amount) ?? 0;
|
|
||||||
var invoiceNow = invoiceAmount >= prorateThreshold;
|
|
||||||
if (invoiceNow)
|
|
||||||
{
|
|
||||||
await ProcessImmediateInvoiceAsync(subscriber, upcomingPreview, invoiceAmount, customer, itemsForInvoice, pendingInvoiceItems, paymentIntentClientSecret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new InvoicePreviewResult { IsInvoicedNow = invoiceNow, PaymentIntentClientSecret = paymentIntentClientSecret };
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<InvoicePreviewResult> ProcessImmediateInvoiceAsync(ISubscriber subscriber, Invoice upcomingPreview, long invoiceAmount,
|
|
||||||
Customer customer, IEnumerable<InvoiceLineItem> itemsForInvoice, PendingInoviceItems pendingInvoiceItems,
|
|
||||||
string paymentIntentClientSecret)
|
|
||||||
{
|
|
||||||
// Owes more than prorateThreshold on the next invoice.
|
|
||||||
// Invoice them and pay now instead of waiting until the next billing cycle.
|
|
||||||
|
|
||||||
string cardPaymentMethodId = null;
|
|
||||||
var invoiceAmountDue = upcomingPreview.StartingBalance + invoiceAmount;
|
|
||||||
cardPaymentMethodId = GetCardPaymentMethodId(invoiceAmountDue, customer, cardPaymentMethodId);
|
|
||||||
|
|
||||||
Stripe.Invoice invoice = null;
|
|
||||||
var createdInvoiceItems = new List<Stripe.InvoiceItem>();
|
|
||||||
Braintree.Transaction braintreeTransaction = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await CreateInvoiceItemsAsync(subscriber, itemsForInvoice, pendingInvoiceItems, createdInvoiceItems);
|
|
||||||
|
|
||||||
invoice = await CreateInvoiceAsync(subscriber, cardPaymentMethodId);
|
|
||||||
|
|
||||||
var invoicePayOptions = new Stripe.InvoicePayOptions();
|
|
||||||
await CreateBrainTreeTransactionRequestAsync(subscriber, invoice, customer, invoicePayOptions,
|
|
||||||
cardPaymentMethodId, braintreeTransaction);
|
|
||||||
|
|
||||||
await InvoicePayAsync(invoicePayOptions, invoice, paymentIntentClientSecret);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
if (braintreeTransaction != null)
|
|
||||||
{
|
|
||||||
await _btGateway.Transaction.RefundAsync(braintreeTransaction.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invoice != null)
|
|
||||||
{
|
|
||||||
if (invoice.Status == "paid")
|
|
||||||
{
|
|
||||||
// It's apparently paid, so we return without throwing an exception
|
|
||||||
return new InvoicePreviewResult
|
|
||||||
{
|
|
||||||
IsInvoicedNow = false,
|
|
||||||
PaymentIntentClientSecret = paymentIntentClientSecret
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
await RestoreInvoiceItemsAsync(invoice, customer, pendingInvoiceItems.PendingInvoiceItems);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var ii in createdInvoiceItems)
|
|
||||||
{
|
|
||||||
await _stripeAdapter.InvoiceDeleteAsync(ii.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e is Stripe.StripeException strEx &&
|
|
||||||
(strEx.StripeError?.Message?.Contains("cannot be used because it is not verified") ?? false))
|
|
||||||
{
|
|
||||||
throw new GatewayException("Bank account is not yet verified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new InvoicePreviewResult
|
|
||||||
{
|
|
||||||
IsInvoicedNow = false,
|
|
||||||
PaymentIntentClientSecret = paymentIntentClientSecret
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<InvoiceLineItem> GetItemsForInvoice(List<InvoiceSubscriptionItemOptions> subItemOptions, Invoice upcomingPreview,
|
|
||||||
PendingInoviceItems pendingInvoiceItems)
|
|
||||||
{
|
|
||||||
var itemsForInvoice = upcomingPreview.Lines?.Data?
|
|
||||||
.Where(i => pendingInvoiceItems.PendingInvoiceItemsDict.ContainsKey(i.Id) ||
|
|
||||||
(i.Plan.Id == subItemOptions[0]?.Plan && i.Proration));
|
|
||||||
return itemsForInvoice;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PendingInoviceItems GetPendingInvoiceItems(ISubscriber subscriber)
|
|
||||||
{
|
|
||||||
var pendingInvoiceItems = new PendingInoviceItems();
|
|
||||||
var invoiceItems = _stripeAdapter.InvoiceItemListAsync(new Stripe.InvoiceItemListOptions
|
|
||||||
{
|
|
||||||
Customer = subscriber.GatewayCustomerId
|
|
||||||
}).ToList().Where(i => i.InvoiceId == null);
|
|
||||||
pendingInvoiceItems.PendingInvoiceItemsDict = invoiceItems.ToDictionary(pii => pii.Id);
|
|
||||||
return pendingInvoiceItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Customer> CheckInAppPurchaseMethod(ISubscriber subscriber)
|
|
||||||
{
|
|
||||||
var customerOptions = GetCustomerPaymentOptions();
|
|
||||||
var customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId, customerOptions);
|
|
||||||
var usingInAppPaymentMethod = customer.Metadata.ContainsKey("appleReceipt");
|
|
||||||
if (usingInAppPaymentMethod)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("Cannot perform this action with in-app purchase payment method. " +
|
|
||||||
"Contact support.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return customer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCardPaymentMethodId(long invoiceAmountDue, Customer customer, string cardPaymentMethodId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (invoiceAmountDue <= 0 || customer.Metadata.ContainsKey("btCustomerId")) return cardPaymentMethodId;
|
|
||||||
var hasDefaultCardPaymentMethod = customer.InvoiceSettings?.DefaultPaymentMethod?.Type == "card";
|
|
||||||
var hasDefaultValidSource = customer.DefaultSource != null &&
|
|
||||||
(customer.DefaultSource is Stripe.Card ||
|
|
||||||
customer.DefaultSource is Stripe.BankAccount);
|
|
||||||
if (hasDefaultCardPaymentMethod || hasDefaultValidSource) return cardPaymentMethodId;
|
|
||||||
cardPaymentMethodId = GetLatestCardPaymentMethod(customer.Id)?.Id;
|
|
||||||
if (cardPaymentMethodId == null)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("No payment method is available.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("No payment method is available.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return cardPaymentMethodId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Invoice> GetUpcomingInvoiceAsync(ISubscriber subscriber, List<InvoiceSubscriptionItemOptions> subItemOptions)
|
|
||||||
{
|
|
||||||
var upcomingPreview = await _stripeAdapter.InvoiceUpcomingAsync(new Stripe.UpcomingInvoiceOptions
|
|
||||||
{
|
|
||||||
Customer = subscriber.GatewayCustomerId,
|
|
||||||
Subscription = subscriber.GatewaySubscriptionId,
|
|
||||||
SubscriptionItems = subItemOptions
|
|
||||||
});
|
|
||||||
return upcomingPreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task RestoreInvoiceItemsAsync(Invoice invoice, Customer customer, IEnumerable<InvoiceItem> pendingInvoiceItems)
|
|
||||||
{
|
|
||||||
invoice = await _stripeAdapter.InvoiceVoidInvoiceAsync(invoice.Id, new Stripe.InvoiceVoidOptions());
|
|
||||||
if (invoice.StartingBalance != 0)
|
|
||||||
{
|
|
||||||
await _stripeAdapter.CustomerUpdateAsync(customer.Id,
|
|
||||||
new Stripe.CustomerUpdateOptions { Balance = customer.Balance });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore invoice items that were brought in
|
|
||||||
foreach (var item in pendingInvoiceItems)
|
|
||||||
{
|
|
||||||
var i = new Stripe.InvoiceItemCreateOptions
|
|
||||||
{
|
|
||||||
Currency = item.Currency,
|
|
||||||
Description = item.Description,
|
|
||||||
Customer = item.CustomerId,
|
|
||||||
Subscription = item.SubscriptionId,
|
|
||||||
Discountable = item.Discountable,
|
|
||||||
Metadata = item.Metadata,
|
|
||||||
Quantity = item.Proration ? 1 : item.Quantity,
|
|
||||||
UnitAmount = item.UnitAmount
|
|
||||||
};
|
|
||||||
await _stripeAdapter.InvoiceItemCreateAsync(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task InvoicePayAsync(InvoicePayOptions invoicePayOptions, Invoice invoice, string paymentIntentClientSecret)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await _stripeAdapter.InvoicePayAsync(invoice.Id, invoicePayOptions);
|
|
||||||
}
|
|
||||||
catch (Stripe.StripeException e)
|
|
||||||
{
|
|
||||||
if (e.HttpStatusCode == System.Net.HttpStatusCode.PaymentRequired &&
|
|
||||||
e.StripeError?.Code == "invoice_payment_intent_requires_action")
|
|
||||||
{
|
|
||||||
// SCA required, get intent client secret
|
|
||||||
var invoiceGetOptions = new Stripe.InvoiceGetOptions();
|
|
||||||
invoiceGetOptions.AddExpand("payment_intent");
|
|
||||||
invoice = await _stripeAdapter.InvoiceGetAsync(invoice.Id, invoiceGetOptions);
|
|
||||||
paymentIntentClientSecret = invoice?.PaymentIntent?.ClientSecret;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new GatewayException("Unable to pay invoice.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CreateBrainTreeTransactionRequestAsync(ISubscriber subscriber, Invoice invoice, Customer customer,
|
|
||||||
InvoicePayOptions invoicePayOptions, string cardPaymentMethodId, Braintree.Transaction braintreeTransaction)
|
|
||||||
{
|
|
||||||
if (invoice.AmountDue > 0)
|
|
||||||
{
|
|
||||||
if (customer?.Metadata?.ContainsKey("btCustomerId") ?? false)
|
|
||||||
{
|
|
||||||
invoicePayOptions.PaidOutOfBand = true;
|
|
||||||
var btInvoiceAmount = (invoice.AmountDue / 100M);
|
|
||||||
var transactionResult = await _btGateway.Transaction.SaleAsync(
|
|
||||||
new Braintree.TransactionRequest
|
|
||||||
{
|
|
||||||
Amount = btInvoiceAmount,
|
|
||||||
CustomerId = customer.Metadata["btCustomerId"],
|
|
||||||
Options = new Braintree.TransactionOptionsRequest
|
|
||||||
{
|
|
||||||
SubmitForSettlement = true,
|
|
||||||
PayPal = new Braintree.TransactionOptionsPayPalRequest
|
|
||||||
{
|
|
||||||
CustomField = $"{subscriber.BraintreeIdField()}:{subscriber.Id}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CustomFields = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
[subscriber.BraintreeIdField()] = subscriber.Id.ToString()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!transactionResult.IsSuccess())
|
|
||||||
{
|
|
||||||
throw new GatewayException("Failed to charge PayPal customer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
braintreeTransaction = transactionResult.Target;
|
|
||||||
await _stripeAdapter.InvoiceUpdateAsync(invoice.Id, new Stripe.InvoiceUpdateOptions
|
|
||||||
{
|
|
||||||
Metadata = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
["btTransactionId"] = braintreeTransaction.Id,
|
|
||||||
["btPayPalTransactionId"] =
|
|
||||||
braintreeTransaction.PayPalDetails.AuthorizationId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
invoicePayOptions.OffSession = true;
|
|
||||||
invoicePayOptions.PaymentMethod = cardPaymentMethodId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Invoice> CreateInvoiceAsync(ISubscriber subscriber, string cardPaymentMethodId)
|
|
||||||
{
|
|
||||||
Invoice invoice;
|
|
||||||
invoice = await _stripeAdapter.InvoiceCreateAsync(new Stripe.InvoiceCreateOptions
|
|
||||||
{
|
|
||||||
CollectionMethod = "send_invoice",
|
|
||||||
DaysUntilDue = 1,
|
|
||||||
Customer = subscriber.GatewayCustomerId,
|
|
||||||
Subscription = subscriber.GatewaySubscriptionId,
|
|
||||||
DefaultPaymentMethod = cardPaymentMethodId
|
|
||||||
});
|
|
||||||
return invoice;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CreateInvoiceItemsAsync(ISubscriber subscriber, IEnumerable<InvoiceLineItem> itemsForInvoice,
|
|
||||||
PendingInoviceItems pendingInvoiceItems, List<InvoiceItem> createdInvoiceItems)
|
|
||||||
{
|
|
||||||
foreach (var invoiceLineItem in itemsForInvoice)
|
|
||||||
{
|
|
||||||
if (pendingInvoiceItems.PendingInvoiceItemsDict.ContainsKey(invoiceLineItem.Id))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var invoiceItem = await _stripeAdapter.InvoiceItemCreateAsync(new Stripe.InvoiceItemCreateOptions
|
|
||||||
{
|
|
||||||
Currency = invoiceLineItem.Currency,
|
|
||||||
Description = invoiceLineItem.Description,
|
|
||||||
Customer = subscriber.GatewayCustomerId,
|
|
||||||
Subscription = invoiceLineItem.Subscription,
|
|
||||||
Discountable = invoiceLineItem.Discountable,
|
|
||||||
Amount = invoiceLineItem.Amount
|
|
||||||
});
|
|
||||||
createdInvoiceItems.Add(invoiceItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CancelSubscriptionAsync(ISubscriber subscriber, bool endOfPeriod = false,
|
public async Task CancelSubscriptionAsync(ISubscriber subscriber, bool endOfPeriod = false,
|
||||||
bool skipInAppPurchaseCheck = false)
|
bool skipInAppPurchaseCheck = false)
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models;
|
using Bit.Core.Auth.Models;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
|
using Bit.Core.Auth.Utilities;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -61,9 +64,8 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
|||||||
private readonly IAcceptOrgUserCommand _acceptOrgUserCommand;
|
private readonly IAcceptOrgUserCommand _acceptOrgUserCommand;
|
||||||
private readonly IProviderUserRepository _providerUserRepository;
|
private readonly IProviderUserRepository _providerUserRepository;
|
||||||
private readonly IStripeSyncService _stripeSyncService;
|
private readonly IStripeSyncService _stripeSyncService;
|
||||||
private readonly IWebAuthnCredentialRepository _webAuthnCredentialRepository;
|
|
||||||
private readonly IDataProtectorTokenFactory<WebAuthnLoginTokenable> _webAuthnLoginTokenizer;
|
|
||||||
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory;
|
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory;
|
||||||
|
private readonly IWebAuthnCredentialRepository _webAuthnCredentialRepository;
|
||||||
|
|
||||||
public UserService(
|
public UserService(
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
@ -96,8 +98,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
|||||||
IProviderUserRepository providerUserRepository,
|
IProviderUserRepository providerUserRepository,
|
||||||
IStripeSyncService stripeSyncService,
|
IStripeSyncService stripeSyncService,
|
||||||
IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory,
|
IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory,
|
||||||
IWebAuthnCredentialRepository webAuthnRepository,
|
IWebAuthnCredentialRepository webAuthnRepository)
|
||||||
IDataProtectorTokenFactory<WebAuthnLoginTokenable> webAuthnLoginTokenizer)
|
|
||||||
: base(
|
: base(
|
||||||
store,
|
store,
|
||||||
optionsAccessor,
|
optionsAccessor,
|
||||||
@ -136,7 +137,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
|||||||
_stripeSyncService = stripeSyncService;
|
_stripeSyncService = stripeSyncService;
|
||||||
_orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory;
|
_orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory;
|
||||||
_webAuthnCredentialRepository = webAuthnRepository;
|
_webAuthnCredentialRepository = webAuthnRepository;
|
||||||
_webAuthnLoginTokenizer = webAuthnLoginTokenizer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid? GetProperUserId(ClaimsPrincipal principal)
|
public Guid? GetProperUserId(ClaimsPrincipal principal)
|
||||||
@ -586,45 +586,33 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AssertionOptions> StartWebAuthnLoginAssertionAsync(User user)
|
public AssertionOptions StartWebAuthnLoginAssertion()
|
||||||
{
|
{
|
||||||
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.WebAuthn);
|
return _fido2.GetAssertionOptions(Enumerable.Empty<PublicKeyCredentialDescriptor>(), UserVerificationRequirement.Required);
|
||||||
var existingKeys = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id);
|
|
||||||
var existingCredentials = existingKeys
|
|
||||||
.Select(k => new PublicKeyCredentialDescriptor(CoreHelpers.Base64UrlDecode(k.CredentialId)))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (existingCredentials.Count == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: PRF?
|
public async Task<(User, WebAuthnCredential)> CompleteWebAuthLoginAssertionAsync(AssertionOptions options, AuthenticatorAssertionRawResponse assertionResponse)
|
||||||
var exts = new AuthenticationExtensionsClientInputs
|
|
||||||
{
|
{
|
||||||
UserVerificationMethod = true
|
if (!GuidUtilities.TryParseBytes(assertionResponse.Response.UserHandle, out var userId))
|
||||||
};
|
{
|
||||||
var options = _fido2.GetAssertionOptions(existingCredentials, UserVerificationRequirement.Required, exts);
|
throw new BadRequestException("Invalid credential.");
|
||||||
|
|
||||||
// TODO: temp save options to user record somehow
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> CompleteWebAuthLoginAssertionAsync(AuthenticatorAssertionRawResponse assertionResponse, User user)
|
var user = await _userRepository.GetByIdAsync(userId);
|
||||||
|
if (user == null)
|
||||||
{
|
{
|
||||||
// TODO: Get options from user record somehow, then clear them
|
throw new BadRequestException("Invalid credential.");
|
||||||
var options = AssertionOptions.FromJson("");
|
}
|
||||||
|
|
||||||
var userCredentials = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id);
|
var userCredentials = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id);
|
||||||
var assertionId = CoreHelpers.Base64UrlEncode(assertionResponse.Id);
|
var assertedCredentialId = CoreHelpers.Base64UrlEncode(assertionResponse.Id);
|
||||||
var credential = userCredentials.FirstOrDefault(c => c.CredentialId == assertionId);
|
var credential = userCredentials.FirstOrDefault(c => c.CredentialId == assertedCredentialId);
|
||||||
if (credential == null)
|
if (credential == null)
|
||||||
{
|
{
|
||||||
return null;
|
throw new BadRequestException("Invalid credential.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Callback to ensure credential ID is unique. Do we care? I don't think so.
|
// Always return true, since we've already filtered the credentials after user id
|
||||||
IsUserHandleOwnerOfCredentialIdAsync callback = (args, cancellationToken) => Task.FromResult(true);
|
IsUserHandleOwnerOfCredentialIdAsync callback = (args, cancellationToken) => Task.FromResult(true);
|
||||||
var credentialPublicKey = CoreHelpers.Base64UrlDecode(credential.PublicKey);
|
var credentialPublicKey = CoreHelpers.Base64UrlDecode(credential.PublicKey);
|
||||||
var assertionVerificationResult = await _fido2.MakeAssertionAsync(
|
var assertionVerificationResult = await _fido2.MakeAssertionAsync(
|
||||||
@ -634,15 +622,12 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
|||||||
credential.Counter = (int)assertionVerificationResult.Counter;
|
credential.Counter = (int)assertionVerificationResult.Counter;
|
||||||
await _webAuthnCredentialRepository.ReplaceAsync(credential);
|
await _webAuthnCredentialRepository.ReplaceAsync(credential);
|
||||||
|
|
||||||
if (assertionVerificationResult.Status == "ok")
|
if (assertionVerificationResult.Status != "ok")
|
||||||
{
|
{
|
||||||
var token = _webAuthnLoginTokenizer.Protect(new WebAuthnLoginTokenable(user));
|
throw new BadRequestException("Invalid credential.");
|
||||||
return token;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (user, credential);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendEmailVerificationAsync(User user)
|
public async Task SendEmailVerificationAsync(User user)
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
namespace Bit.Core.Tools.Entities;
|
#nullable enable
|
||||||
|
using Bit.Core.Tools.Models.Business;
|
||||||
|
|
||||||
|
namespace Bit.Core.Tools.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An entity that can be referenced by a <see cref="ReferenceEvent"/>.
|
||||||
|
/// </summary>
|
||||||
public interface IReferenceable
|
public interface IReferenceable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies the entity that generated the event.
|
||||||
|
/// </summary>
|
||||||
Guid Id { get; set; }
|
Guid Id { get; set; }
|
||||||
string ReferenceData { get; set; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contextual information included in the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Do not store secrets in this field.
|
||||||
|
/// </remarks>
|
||||||
|
string? ReferenceData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <see langword="true" /> when the entity is a user.
|
||||||
|
/// Otherwise returns <see langword="false" />.
|
||||||
|
/// </summary>
|
||||||
bool IsUser();
|
bool IsUser();
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,125 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Tools.Enums;
|
using Bit.Core.Tools.Enums;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Tools.Entities;
|
namespace Bit.Core.Tools.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An end-to-end encrypted secret accessible to arbitrary
|
||||||
|
/// entities through a fixed URI.
|
||||||
|
/// </summary>
|
||||||
public class Send : ITableObject<Guid>
|
public class Send : ITableObject<Guid>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Uniquely identifies this send.
|
||||||
|
/// </summary>
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies the user that created this send.
|
||||||
|
/// </summary>
|
||||||
public Guid? UserId { get; set; }
|
public Guid? UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies the organization that created this send.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Not presently in-use by client applications.
|
||||||
|
/// </remarks>
|
||||||
public Guid? OrganizationId { get; set; }
|
public Guid? OrganizationId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the data being sent. This field determines how
|
||||||
|
/// the <see cref="Data"/> field is interpreted.
|
||||||
|
/// </summary>
|
||||||
public SendType Type { get; set; }
|
public SendType Type { get; set; }
|
||||||
public string Data { get; set; }
|
|
||||||
public string Key { get; set; }
|
/// <summary>
|
||||||
|
/// Stores data containing or pointing to the transmitted secret. JSON.
|
||||||
|
/// </summary>
|
||||||
|
/// <note>
|
||||||
|
/// Must be nullable due to several database column configuration.
|
||||||
|
/// The application and all other databases assume this is not nullable.
|
||||||
|
/// Tech debt ticket: PM-4128
|
||||||
|
/// </note>
|
||||||
|
public string? Data { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the data's encryption key. Encrypted.
|
||||||
|
/// </summary>
|
||||||
|
/// <note>
|
||||||
|
/// Must be nullable due to MySql database column configuration.
|
||||||
|
/// The application and all other databases assume this is not nullable.
|
||||||
|
/// Tech debt ticket: PM-4128
|
||||||
|
/// </note>
|
||||||
|
public string? Key { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Password provided by the user. Protected with pbkdf2.
|
||||||
|
/// </summary>
|
||||||
[MaxLength(300)]
|
[MaxLength(300)]
|
||||||
public string Password { get; set; }
|
public string? Password { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The send becomes unavailable to API callers when
|
||||||
|
/// <see cref="AccessCount"/> >= <see cref="MaxAccessCount"/>.
|
||||||
|
/// </summary>
|
||||||
public int? MaxAccessCount { get; set; }
|
public int? MaxAccessCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of times the content was accessed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This value is owned by the server. Clients cannot alter it.
|
||||||
|
/// </remarks>
|
||||||
public int AccessCount { get; set; }
|
public int AccessCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date this send was created.
|
||||||
|
/// </summary>
|
||||||
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date this send was last modified.
|
||||||
|
/// </summary>
|
||||||
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date this send becomes unavailable to API callers.
|
||||||
|
/// </summary>
|
||||||
public DateTime? ExpirationDate { get; set; }
|
public DateTime? ExpirationDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date this send will be unconditionally deleted.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is set by server-side when the user doesn't specify a deletion date.
|
||||||
|
/// </remarks>
|
||||||
public DateTime DeletionDate { get; set; }
|
public DateTime DeletionDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When this is true the send is not available to API callers,
|
||||||
|
/// unless they're the creator.
|
||||||
|
/// </summary>
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the creator's email address should be shown to the recipient.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="false"/> indicates the email may be shown.
|
||||||
|
/// <see langword="true"/> indicates the email should be hidden.
|
||||||
|
/// <see langword="null"/> indicates the client doesn't set the field and
|
||||||
|
/// the email should be hidden.
|
||||||
|
/// </value>
|
||||||
public bool? HideEmail { get; set; }
|
public bool? HideEmail { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the send's <see cref="Id" />
|
||||||
|
/// </summary>
|
||||||
public void SetNewId()
|
public void SetNewId()
|
||||||
{
|
{
|
||||||
Id = CoreHelpers.GenerateComb();
|
Id = CoreHelpers.GenerateComb();
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
@ -6,10 +8,23 @@ using Bit.Core.Tools.Enums;
|
|||||||
|
|
||||||
namespace Bit.Core.Tools.Models.Business;
|
namespace Bit.Core.Tools.Models.Business;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Product support monitoring.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Do not store secrets in this type.
|
||||||
|
/// </remarks>
|
||||||
public class ReferenceEvent
|
public class ReferenceEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a <see cref="ReferenceEvent"/>.
|
||||||
|
/// </summary>
|
||||||
public ReferenceEvent() { }
|
public ReferenceEvent() { }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ReferenceEvent()" />
|
||||||
|
/// <param name="type">Monitored event type.</param>
|
||||||
|
/// <param name="source">Entity that created the event.</param>
|
||||||
|
/// <param name="currentContext">The conditions in which the event occurred.</param>
|
||||||
public ReferenceEvent(ReferenceEventType type, IReferenceable source, ICurrentContext currentContext)
|
public ReferenceEvent(ReferenceEventType type, IReferenceable source, ICurrentContext currentContext)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
@ -26,48 +41,197 @@ public class ReferenceEvent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Monitored event type.
|
||||||
|
/// </summary>
|
||||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public ReferenceEventType Type { get; set; }
|
public ReferenceEventType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The kind of entity that created the event.
|
||||||
|
/// </summary>
|
||||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public ReferenceEventSource Source { get; set; }
|
public ReferenceEventSource Source { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IReferenceable.Id"/>
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string ReferenceData { get; set; }
|
/// <inheritdoc cref="IReferenceable.ReferenceData"/>
|
||||||
|
public string? ReferenceData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moment the event occurred.
|
||||||
|
/// </summary>
|
||||||
public DateTime EventDate { get; set; } = DateTime.UtcNow;
|
public DateTime EventDate { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of users sent invitations by an organization.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.InvitedUsers"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public int? Users { get; set; }
|
public int? Users { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not a subscription was canceled immediately or at the end of the billing period.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> when a cancellation occurs immediately.
|
||||||
|
/// <see langword="false"/> when a cancellation occurs at the end of a customer's billing period.
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.CancelSubscription"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public bool? EndOfPeriod { get; set; }
|
public bool? EndOfPeriod { get; set; }
|
||||||
|
|
||||||
public string PlanName { get; set; }
|
/// <summary>
|
||||||
|
/// Branded name of the subscription.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only for subscription management events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
|
public string? PlanName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies a subscription.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only for subscription management events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public PlanType? PlanType { get; set; }
|
public PlanType? PlanType { get; set; }
|
||||||
|
|
||||||
public string OldPlanName { get; set; }
|
/// <summary>
|
||||||
|
/// The branded name of the prior plan.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.UpgradePlan"/> events
|
||||||
|
/// initiated by organizations.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
|
public string? OldPlanName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies the prior plan
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.UpgradePlan"/> events
|
||||||
|
/// initiated by organizations.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public PlanType? OldPlanType { get; set; }
|
public PlanType? OldPlanType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Seat count when a billable action occurs. When adjusting seats, contains
|
||||||
|
/// the new seat count.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.Rebilled"/>,
|
||||||
|
/// <see cref="ReferenceEventType.AdjustSeats"/>, <see cref="ReferenceEventType.UpgradePlan"/>,
|
||||||
|
/// and <see cref="ReferenceEventType.Signup"/> events initiated by organizations.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public int? Seats { get; set; }
|
public int? Seats { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Seat count when a seat adjustment occurs.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.AdjustSeats"/>
|
||||||
|
/// events initiated by organizations.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public int? PreviousSeats { get; set; }
|
public int? PreviousSeats { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Qty in GB of storage. When adjusting storage, contains the adjusted
|
||||||
|
/// storage qty. Otherwise contains the total storage quantity.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.Rebilled"/>,
|
||||||
|
/// <see cref="ReferenceEventType.AdjustStorage"/>, <see cref="ReferenceEventType.UpgradePlan"/>,
|
||||||
|
/// and <see cref="ReferenceEventType.Signup"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public short? Storage { get; set; }
|
public short? Storage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The type of send created or accessed.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.SendAccessed"/>
|
||||||
|
/// and <see cref="ReferenceEventType.SendCreated"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public SendType? SendType { get; set; }
|
public SendType? SendType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the send has private notes.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> when the send has private notes, otherwise <see langword="false"/>.
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.SendAccessed"/>
|
||||||
|
/// and <see cref="ReferenceEventType.SendCreated"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public bool? SendHasNotes { get; set; }
|
public bool? SendHasNotes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The send expires after its access count exceeds this value.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// This field only contains a value when the send has a max access count
|
||||||
|
/// and <see cref="Type"/> is <see cref="ReferenceEventType.SendAccessed"/>
|
||||||
|
/// or <see cref="ReferenceEventType.SendCreated"/> events.
|
||||||
|
/// Otherwise, the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public int? MaxAccessCount { get; set; }
|
public int? MaxAccessCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the created send has a password.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.SendAccessed"/>
|
||||||
|
/// and <see cref="ReferenceEventType.SendCreated"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public bool? HasPassword { get; set; }
|
public bool? HasPassword { get; set; }
|
||||||
|
|
||||||
public string EventRaisedByUser { get; set; }
|
/// <summary>
|
||||||
|
/// The administrator that performed the action.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.OrganizationCreatedByAdmin"/>
|
||||||
|
/// and <see cref="ReferenceEventType.OrganizationEditedByAdmin"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
|
public string? EventRaisedByUser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not an organization's trial period was started by a sales person.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a value only on <see cref="ReferenceEventType.OrganizationCreatedByAdmin"/>
|
||||||
|
/// and <see cref="ReferenceEventType.OrganizationEditedByAdmin"/> events.
|
||||||
|
/// Otherwise the value should be <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
public bool? SalesAssistedTrialStarted { get; set; }
|
public bool? SalesAssistedTrialStarted { get; set; }
|
||||||
|
|
||||||
public string ClientId { get; set; }
|
/// <summary>
|
||||||
public Version ClientVersion { get; set; }
|
/// The installation id of the application that originated the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="null"/> when the event was not originated by an application.
|
||||||
|
/// </value>
|
||||||
|
public string? ClientId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The version of the client application that originated the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="null"/> when the event was not originated by an application.
|
||||||
|
/// </value>
|
||||||
|
public Version? ClientVersion { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,33 @@
|
|||||||
namespace Bit.Core.Tools.Models.Data;
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Bit.Core.Tools.Models.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shared data for a send
|
||||||
|
/// </summary>
|
||||||
public abstract class SendData
|
public abstract class SendData
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a <see cref="SendData"/>.
|
||||||
|
/// </summary>
|
||||||
public SendData() { }
|
public SendData() { }
|
||||||
|
|
||||||
public SendData(string name, string notes)
|
/// <inheritdoc cref="SendData()" />
|
||||||
|
/// <param name="name">User-provided name of the send.</param>
|
||||||
|
/// <param name="notes">User-provided private notes of the send.</param>
|
||||||
|
public SendData(string name, string? notes)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Notes = notes;
|
Notes = notes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
/// <summary>
|
||||||
public string Notes { get; set; }
|
/// User-provided name of the send.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User-provided private notes of the send.
|
||||||
|
/// </summary>
|
||||||
|
public string? Notes { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,64 @@
|
|||||||
using System.Text.Json.Serialization;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using static System.Text.Json.Serialization.JsonNumberHandling;
|
||||||
|
|
||||||
namespace Bit.Core.Tools.Models.Data;
|
namespace Bit.Core.Tools.Models.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A file secret being sent.
|
||||||
|
/// </summary>
|
||||||
public class SendFileData : SendData
|
public class SendFileData : SendData
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a <see cref="SendFileData"/>.
|
||||||
|
/// </summary>
|
||||||
public SendFileData() { }
|
public SendFileData() { }
|
||||||
|
|
||||||
public SendFileData(string name, string notes, string fileName)
|
/// <inheritdoc cref="SendFileData()"/>
|
||||||
|
/// <param name="name">Attached file name.</param>
|
||||||
|
/// <param name="notes">User-provided private notes of the send.</param>
|
||||||
|
/// <param name="fileName">Attached file name.</param>
|
||||||
|
public SendFileData(string name, string? notes, string fileName)
|
||||||
: base(name, notes)
|
: base(name, notes)
|
||||||
{
|
{
|
||||||
FileName = fileName;
|
FileName = fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We serialize Size as a string since JSON (or Javascript) doesn't support full precision for long numbers
|
/// <summary>
|
||||||
[JsonNumberHandling(JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowReadingFromString)]
|
/// Size of the attached file in bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Serialized as a string since JSON (or Javascript) doesn't support
|
||||||
|
/// full precision for long numbers
|
||||||
|
/// </remarks>
|
||||||
|
[JsonNumberHandling(WriteAsString | AllowReadingFromString)]
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
|
|
||||||
public string Id { get; set; }
|
/// <summary>
|
||||||
public string FileName { get; set; }
|
/// Uniquely identifies an uploaded file.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain <see langword="null" /> only when a file
|
||||||
|
/// upload is pending. Should never contain null once the
|
||||||
|
/// file upload completes.
|
||||||
|
/// </value>
|
||||||
|
[DisallowNull]
|
||||||
|
public string? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attached file name.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Should contain a non-empty string once the file upload completes.
|
||||||
|
/// </value>
|
||||||
|
public string FileName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When true the uploaded file's length was confirmed within
|
||||||
|
/// the expected tolerance and below the maximum supported
|
||||||
|
/// file size.
|
||||||
|
/// </summary>
|
||||||
public bool Validated { get; set; } = true;
|
public bool Validated { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,42 @@
|
|||||||
namespace Bit.Core.Tools.Models.Data;
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Bit.Core.Tools.Models.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A text secret being sent.
|
||||||
|
/// </summary>
|
||||||
public class SendTextData : SendData
|
public class SendTextData : SendData
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a <see cref="SendTextData"/>.
|
||||||
|
/// </summary>
|
||||||
public SendTextData() { }
|
public SendTextData() { }
|
||||||
|
|
||||||
public SendTextData(string name, string notes, string text, bool hidden)
|
/// <inheritdoc cref="SendTextData()"/>
|
||||||
|
/// <param name="name">Attached file name.</param>
|
||||||
|
/// <param name="notes">User-provided private notes of the send.</param>
|
||||||
|
/// <param name="text">The secret being sent.</param>
|
||||||
|
/// <param name="hidden">
|
||||||
|
/// Indicates whether the secret should be concealed when opening the send.
|
||||||
|
/// </param>
|
||||||
|
public SendTextData(string name, string? notes, string? text, bool hidden)
|
||||||
: base(name, notes)
|
: base(name, notes)
|
||||||
{
|
{
|
||||||
Text = text;
|
Text = text;
|
||||||
Hidden = hidden;
|
Hidden = hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text { get; set; }
|
/// <summary>
|
||||||
|
/// The secret being sent.
|
||||||
|
/// </summary>
|
||||||
|
public string? Text { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the secret should be concealed when opening the send.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true" /> when the secret should be concealed.
|
||||||
|
/// Otherwise <see langword="false" />.
|
||||||
|
/// </value>
|
||||||
public bool Hidden { get; set; }
|
public bool Hidden { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,36 @@
|
|||||||
using Bit.Core.Repositories;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
|
|
||||||
namespace Bit.Core.Tools.Repositories;
|
namespace Bit.Core.Tools.Repositories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Service for saving and loading <see cref="Send"/>s in persistent storage.
|
||||||
|
/// </summary>
|
||||||
public interface ISendRepository : IRepository<Send, Guid>
|
public interface ISendRepository : IRepository<Send, Guid>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Loads all <see cref="Send"/>s created by a user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId">
|
||||||
|
/// Identifies the user.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A task that completes once the <see cref="Send"/>s have been loaded.
|
||||||
|
/// The task's result contains the loaded <see cref="Send"/>s.
|
||||||
|
/// </returns>
|
||||||
Task<ICollection<Send>> GetManyByUserIdAsync(Guid userId);
|
Task<ICollection<Send>> GetManyByUserIdAsync(Guid userId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads <see cref="Send"/>s scheduled for deletion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deletionDateBefore">
|
||||||
|
/// Load sends whose <see cref="Send.DeletionDate" /> is < this date.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A task that completes once the <see cref="Send"/>s have been loaded.
|
||||||
|
/// The task's result contains the loaded <see cref="Send"/>s.
|
||||||
|
/// </returns>
|
||||||
Task<ICollection<Send>> GetManyByDeletionDateAsync(DateTime deletionDateBefore);
|
Task<ICollection<Send>> GetManyByDeletionDateAsync(DateTime deletionDateBefore);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Data.Organizations.Policies;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
@ -12,6 +12,7 @@ public class CipherLoginFido2CredentialData
|
|||||||
public string RpId { get; set; }
|
public string RpId { get; set; }
|
||||||
public string RpName { get; set; }
|
public string RpName { get; set; }
|
||||||
public string UserHandle { get; set; }
|
public string UserHandle { get; set; }
|
||||||
|
public string UserName { get; set; }
|
||||||
public string UserDisplayName { get; set; }
|
public string UserDisplayName { get; set; }
|
||||||
public string Counter { get; set; }
|
public string Counter { get; set; }
|
||||||
public string Discoverable { get; set; }
|
public string Discoverable { get; set; }
|
||||||
|
@ -32,7 +32,7 @@ public interface ICipherRepository : IRepository<Cipher, Guid>
|
|||||||
Task UpdateCiphersAsync(Guid userId, IEnumerable<Cipher> ciphers);
|
Task UpdateCiphersAsync(Guid userId, IEnumerable<Cipher> ciphers);
|
||||||
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders);
|
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders);
|
||||||
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Collection> collections,
|
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Collection> collections,
|
||||||
IEnumerable<CollectionCipher> collectionCiphers);
|
IEnumerable<CollectionCipher> collectionCiphers, IEnumerable<CollectionUser> collectionUsers);
|
||||||
Task SoftDeleteAsync(IEnumerable<Guid> ids, Guid userId);
|
Task SoftDeleteAsync(IEnumerable<Guid> ids, Guid userId);
|
||||||
Task SoftDeleteByIdsOrganizationIdAsync(IEnumerable<Guid> ids, Guid organizationId);
|
Task SoftDeleteByIdsOrganizationIdAsync(IEnumerable<Guid> ids, Guid organizationId);
|
||||||
Task<DateTime> RestoreAsync(IEnumerable<Guid> ids, Guid userId);
|
Task<DateTime> RestoreAsync(IEnumerable<Guid> ids, Guid userId);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -25,6 +27,7 @@ public class CipherService : ICipherService
|
|||||||
private readonly ICollectionRepository _collectionRepository;
|
private readonly ICollectionRepository _collectionRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly ICollectionCipherRepository _collectionCipherRepository;
|
private readonly ICollectionCipherRepository _collectionCipherRepository;
|
||||||
private readonly IPushNotificationService _pushService;
|
private readonly IPushNotificationService _pushService;
|
||||||
private readonly IAttachmentStorageService _attachmentStorageService;
|
private readonly IAttachmentStorageService _attachmentStorageService;
|
||||||
@ -42,6 +45,7 @@ public class CipherService : ICipherService
|
|||||||
ICollectionRepository collectionRepository,
|
ICollectionRepository collectionRepository,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
ICollectionCipherRepository collectionCipherRepository,
|
ICollectionCipherRepository collectionCipherRepository,
|
||||||
IPushNotificationService pushService,
|
IPushNotificationService pushService,
|
||||||
IAttachmentStorageService attachmentStorageService,
|
IAttachmentStorageService attachmentStorageService,
|
||||||
@ -57,6 +61,7 @@ public class CipherService : ICipherService
|
|||||||
_collectionRepository = collectionRepository;
|
_collectionRepository = collectionRepository;
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
|
_organizationUserRepository = organizationUserRepository;
|
||||||
_collectionCipherRepository = collectionCipherRepository;
|
_collectionCipherRepository = collectionCipherRepository;
|
||||||
_pushService = pushService;
|
_pushService = pushService;
|
||||||
_attachmentStorageService = attachmentStorageService;
|
_attachmentStorageService = attachmentStorageService;
|
||||||
@ -745,6 +750,7 @@ public class CipherService : ICipherService
|
|||||||
var org = collections.Count > 0 ?
|
var org = collections.Count > 0 ?
|
||||||
await _organizationRepository.GetByIdAsync(collections[0].OrganizationId) :
|
await _organizationRepository.GetByIdAsync(collections[0].OrganizationId) :
|
||||||
await _organizationRepository.GetByIdAsync(ciphers.FirstOrDefault(c => c.OrganizationId.HasValue).OrganizationId.Value);
|
await _organizationRepository.GetByIdAsync(ciphers.FirstOrDefault(c => c.OrganizationId.HasValue).OrganizationId.Value);
|
||||||
|
var importingOrgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, importingUserId);
|
||||||
|
|
||||||
if (collections.Count > 0 && org != null && org.MaxCollections.HasValue)
|
if (collections.Count > 0 && org != null && org.MaxCollections.HasValue)
|
||||||
{
|
{
|
||||||
@ -762,18 +768,25 @@ public class CipherService : ICipherService
|
|||||||
cipher.SetNewId();
|
cipher.SetNewId();
|
||||||
}
|
}
|
||||||
|
|
||||||
var userCollectionsIds = (await _collectionRepository.GetManyByOrganizationIdAsync(org.Id)).Select(c => c.Id).ToList();
|
var organizationCollectionsIds = (await _collectionRepository.GetManyByOrganizationIdAsync(org.Id)).Select(c => c.Id).ToList();
|
||||||
|
|
||||||
//Assign id to the ones that don't exist in DB
|
//Assign id to the ones that don't exist in DB
|
||||||
//Need to keep the list order to create the relationships
|
//Need to keep the list order to create the relationships
|
||||||
List<Collection> newCollections = new List<Collection>();
|
var newCollections = new List<Collection>();
|
||||||
|
var newCollectionUsers = new List<CollectionUser>();
|
||||||
|
|
||||||
foreach (var collection in collections)
|
foreach (var collection in collections)
|
||||||
{
|
{
|
||||||
if (!userCollectionsIds.Contains(collection.Id))
|
if (!organizationCollectionsIds.Contains(collection.Id))
|
||||||
{
|
{
|
||||||
collection.SetNewId();
|
collection.SetNewId();
|
||||||
newCollections.Add(collection);
|
newCollections.Add(collection);
|
||||||
|
newCollectionUsers.Add(new CollectionUser
|
||||||
|
{
|
||||||
|
CollectionId = collection.Id,
|
||||||
|
OrganizationUserId = importingOrgUser.Id,
|
||||||
|
Manage = true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,7 +810,7 @@ public class CipherService : ICipherService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create it all
|
// Create it all
|
||||||
await _cipherRepository.CreateAsync(ciphers, newCollections, collectionCiphers);
|
await _cipherRepository.CreateAsync(ciphers, newCollections, collectionCiphers, newCollectionUsers);
|
||||||
|
|
||||||
// push
|
// push
|
||||||
await _pushService.PushSyncVaultAsync(importingUserId);
|
await _pushService.PushSyncVaultAsync(importingUserId);
|
||||||
|
@ -131,6 +131,16 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[6.0.4, )",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2.AspNet": {
|
"Fido2.AspNet": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[3.0.1, )",
|
"requested": "[3.0.1, )",
|
||||||
@ -150,29 +160,6 @@
|
|||||||
"Microsoft.CSharp": "4.7.0"
|
"Microsoft.CSharp": "4.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[4.1.2, )",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[3.0.1, )",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"LaunchDarkly.ServerSdk": {
|
"LaunchDarkly.ServerSdk": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[8.0.0, )",
|
"requested": "[8.0.0, )",
|
||||||
@ -465,6 +452,15 @@
|
|||||||
"resolved": "2.2.1",
|
"resolved": "2.2.1",
|
||||||
"contentHash": "A6Zr52zVqJKt18ZBsTnX0qhG0kwIQftVAjLmszmkiR/trSp8H+xj1gUOzk7XHwaKgyREMSV1v9XaKrBUeIOdvQ=="
|
"contentHash": "A6Zr52zVqJKt18ZBsTnX0qhG0kwIQftVAjLmszmkiR/trSp8H+xj1gUOzk7XHwaKgyREMSV1v9XaKrBUeIOdvQ=="
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -484,28 +480,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -554,10 +530,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -590,8 +566,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
|
@ -16,8 +16,8 @@ public class Program
|
|||||||
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") ||
|
||||||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator"))
|
||||||
{
|
{
|
||||||
return e.Level >= globalSettings.MinLogLevel.EventsSettings.IdentityToken;
|
return e.Level >= globalSettings.MinLogLevel.EventsSettings.IdentityToken;
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -220,49 +238,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -354,10 +331,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -390,8 +367,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2617,10 +2594,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2648,7 +2624,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2656,7 +2632,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2668,9 +2644,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -220,49 +238,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -354,10 +331,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -390,8 +367,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2617,10 +2594,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2648,7 +2624,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2656,7 +2632,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2668,9 +2644,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,24 @@
|
|||||||
"Microsoft.Win32.Registry": "5.0.0"
|
"Microsoft.Win32.Registry": "5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Duende.IdentityServer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Duende.IdentityServer.Storage": "6.0.4",
|
||||||
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Duende.IdentityServer.Storage": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"IdentityModel": "6.0.0",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Fido2": {
|
"Fido2": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.1",
|
"resolved": "3.0.1",
|
||||||
@ -229,49 +247,8 @@
|
|||||||
},
|
},
|
||||||
"IdentityModel": {
|
"IdentityModel": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==",
|
"contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g=="
|
||||||
"dependencies": {
|
|
||||||
"Newtonsoft.Json": "11.0.2",
|
|
||||||
"System.Text.Encodings.Web": "4.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.0.1",
|
|
||||||
"contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0",
|
|
||||||
"IdentityServer4.Storage": "4.1.2",
|
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0",
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
|
|
||||||
"Newtonsoft.Json": "12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.AccessTokenValidation": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "3.0.1",
|
|
||||||
"contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1",
|
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IdentityServer4.Storage": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.1.2",
|
|
||||||
"contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"IdentityModel": "4.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"LaunchDarkly.Cache": {
|
"LaunchDarkly.Cache": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -363,10 +340,10 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==",
|
"contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0"
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Cryptography.Internal": {
|
"Microsoft.AspNetCore.Cryptography.Internal": {
|
||||||
@ -399,8 +376,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
"Microsoft.AspNetCore.DataProtection.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.1.32",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg=="
|
"contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw=="
|
||||||
},
|
},
|
||||||
"Microsoft.Azure.Amqp": {
|
"Microsoft.Azure.Amqp": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -2626,10 +2603,9 @@
|
|||||||
"BitPay.Light": "[1.0.1907, )",
|
"BitPay.Light": "[1.0.1907, )",
|
||||||
"Braintree": "[5.19.0, )",
|
"Braintree": "[5.19.0, )",
|
||||||
"DnsClient": "[1.7.0, )",
|
"DnsClient": "[1.7.0, )",
|
||||||
|
"Duende.IdentityServer": "[6.0.4, )",
|
||||||
"Fido2.AspNet": "[3.0.1, )",
|
"Fido2.AspNet": "[3.0.1, )",
|
||||||
"Handlebars.Net": "[2.1.2, )",
|
"Handlebars.Net": "[2.1.2, )",
|
||||||
"IdentityServer4": "[4.1.2, )",
|
|
||||||
"IdentityServer4.AccessTokenValidation": "[3.0.1, )",
|
|
||||||
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
"LaunchDarkly.ServerSdk": "[8.0.0, )",
|
||||||
"MailKit": "[4.2.0, )",
|
"MailKit": "[4.2.0, )",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )",
|
||||||
@ -2657,7 +2633,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Dapper": "[2.0.123, )"
|
"Dapper": "[2.0.123, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2665,7 +2641,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )",
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )",
|
||||||
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
"Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )",
|
||||||
@ -2677,9 +2653,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "[2023.10.2, )",
|
"Core": "[2023.10.3, )",
|
||||||
"Infrastructure.Dapper": "[2023.10.2, )",
|
"Infrastructure.Dapper": "[2023.10.3, )",
|
||||||
"Infrastructure.EntityFramework": "[2023.10.2, )"
|
"Infrastructure.EntityFramework": "[2023.10.3, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models.Api.Request.Accounts;
|
using Bit.Core.Auth.Models.Api.Request.Accounts;
|
||||||
using Bit.Core.Auth.Models.Api.Response.Accounts;
|
using Bit.Core.Auth.Models.Api.Response.Accounts;
|
||||||
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Auth.Services;
|
using Bit.Core.Auth.Services;
|
||||||
using Bit.Core.Auth.Utilities;
|
using Bit.Core.Auth.Utilities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -8,9 +10,9 @@ using Bit.Core.Exceptions;
|
|||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Tokens;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.SharedWeb.Utilities;
|
using Bit.SharedWeb.Utilities;
|
||||||
using Fido2NetLib;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Bit.Identity.Controllers;
|
namespace Bit.Identity.Controllers;
|
||||||
@ -23,17 +25,21 @@ public class AccountsController : Controller
|
|||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly ICaptchaValidationService _captchaValidationService;
|
private readonly ICaptchaValidationService _captchaValidationService;
|
||||||
|
private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector;
|
||||||
|
|
||||||
|
|
||||||
public AccountsController(
|
public AccountsController(
|
||||||
ILogger<AccountsController> logger,
|
ILogger<AccountsController> logger,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IUserService userService,
|
IUserService userService,
|
||||||
ICaptchaValidationService captchaValidationService)
|
ICaptchaValidationService captchaValidationService,
|
||||||
|
IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> assertionOptionsDataProtector)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
_captchaValidationService = captchaValidationService;
|
_captchaValidationService = captchaValidationService;
|
||||||
|
_assertionOptionsDataProtector = assertionOptionsDataProtector;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moved from API, If you modify this endpoint, please update API as well. Self hosted installs still use the API endpoints.
|
// Moved from API, If you modify this endpoint, please update API as well. Self hosted installs still use the API endpoints.
|
||||||
@ -75,36 +81,19 @@ public class AccountsController : Controller
|
|||||||
return new PreloginResponseModel(kdfInformation);
|
return new PreloginResponseModel(kdfInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("webauthn-assertion-options")]
|
[HttpGet("webauthn/assertion-options")]
|
||||||
[ApiExplorerSettings(IgnoreApi = true)] // Disable Swagger due to CredentialCreateOptions not converting properly
|
|
||||||
[RequireFeature(FeatureFlagKeys.PasswordlessLogin)]
|
[RequireFeature(FeatureFlagKeys.PasswordlessLogin)]
|
||||||
// TODO: Create proper models for this call
|
public WebAuthnLoginAssertionOptionsResponseModel GetWebAuthnLoginAssertionOptions()
|
||||||
public async Task<AssertionOptions> PostWebAuthnAssertionOptions([FromBody] PreloginRequestModel model)
|
|
||||||
{
|
{
|
||||||
var user = await _userRepository.GetByEmailAsync(model.Email);
|
var options = _userService.StartWebAuthnLoginAssertion();
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
// TODO: return something? possible enumeration attacks with this response
|
|
||||||
return new AssertionOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = await _userService.StartWebAuthnLoginAssertionAsync(user);
|
var tokenable = new WebAuthnLoginAssertionOptionsTokenable(WebAuthnLoginAssertionOptionsScope.Authentication, options);
|
||||||
return options;
|
var token = _assertionOptionsDataProtector.Protect(tokenable);
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("webauthn-assertion")]
|
return new WebAuthnLoginAssertionOptionsResponseModel
|
||||||
[RequireFeature(FeatureFlagKeys.PasswordlessLogin)]
|
|
||||||
// TODO: Create proper models for this call
|
|
||||||
public async Task<string> PostWebAuthnAssertion([FromBody] PreloginRequestModel model)
|
|
||||||
{
|
{
|
||||||
var user = await _userRepository.GetByEmailAsync(model.Email);
|
Options = options,
|
||||||
if (user == null)
|
Token = token
|
||||||
{
|
};
|
||||||
// TODO: proper response here?
|
|
||||||
throw new BadRequestException();
|
|
||||||
}
|
|
||||||
|
|
||||||
var token = await _userService.CompleteWebAuthLoginAssertionAsync(null, user);
|
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user