Skip to content

Commit cbb08bd

Browse files
kpande-kssk-keeper
authored andcommitted
Bug Fix SDK 481 and SDK 482 (#483)
1 parent b808766 commit cbb08bd

7 files changed

Lines changed: 210 additions & 43 deletions

File tree

Commander/vault/RecordCommands.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ public static async Task ShareRecordShareCommand(this VaultContext context, Shar
813813
shareOptions.Expiration = DateTimeOffset.Now + ts;
814814
}
815815
await context.Vault.ShareRecordWithUser(record.Uid, options.Email, shareOptions);
816-
Console.WriteLine("Successfuly shared the record {record.Uid} with user {options.Email}");
816+
Console.WriteLine($"Successfully shared the record {record.Uid} with user {options.Email}");
817817
}
818818
catch (NoActiveShareWithUserException e)
819819
{

KeeperSdk/vault/KeeperNSFMutations.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,20 @@ public bool TryResolveKeeperNSFRecordRemovalFolder(
363363
folderUid = null;
364364
if (operation == KeeperNSFRecordRemoveOperation.OwnerTrash)
365365
{
366+
if (!string.IsNullOrWhiteSpace(folderUidOrName))
367+
{
368+
if (!TryResolveKeeperNSFFolder(folderUidOrName, out var ownerTrashFolder))
369+
{
370+
return false;
371+
}
372+
373+
folderUid = GetKeeperNSFApiFolderUid(ownerTrashFolder);
374+
}
375+
else
376+
{
377+
folderUid = GetKeeperNSFFoldersForRecord(recordUid).FirstOrDefault();
378+
}
379+
366380
return true;
367381
}
368382

PowerCommander/NsfFolderCommands.ps1

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ function Set-KeeperNSFFolderAccess {
7777
.Parameter Role
7878
Access role for grant action: viewer (default), share-manager, content-manager,
7979
content-share-manager, full-manager.
80+
81+
.Parameter ExpireIn
82+
Optional. Share expiration period from now (e.g. 30d, 6mo, 1y, 24h, 30mi), integer minutes,
83+
or a TimeSpan. Same as Grant-KeeperRecordAccess.
84+
85+
.Parameter ExpireAt
86+
Optional. Absolute share expiration as ISO datetime (e.g. 2027-01-01T00:00:00Z).
8087
#>
8188
[CmdletBinding()]
8289
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
@@ -93,7 +100,15 @@ function Set-KeeperNSFFolderAccess {
93100

94101
[Parameter()]
95102
[ValidateSet('viewer', 'share-manager', 'content-manager', 'content-share-manager', 'full-manager')]
96-
[string] $Role = 'viewer'
103+
[string] $Role = 'viewer',
104+
105+
[Alias('expire-in')]
106+
[Parameter()]
107+
[System.Object] $ExpireIn,
108+
109+
[Alias('expire-at')]
110+
[Parameter()]
111+
[string] $ExpireAt
97112
)
98113

99114
try {
@@ -109,11 +124,27 @@ function Set-KeeperNSFFolderAccess {
109124
return
110125
}
111126

127+
$shareOptions = $null
128+
if ($Action -eq 'grant' -and ($ExpireIn -or $ExpireAt)) {
129+
try {
130+
$expirationDto = Get-ExpirationDate -ExpireIn $ExpireIn -ExpireAt $ExpireAt
131+
}
132+
catch {
133+
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
134+
return
135+
}
136+
$shareOptions = New-Object KeeperSecurity.Vault.SharedFolderUserOptions
137+
$shareOptions.Expiration = $expirationDto
138+
}
139+
112140
foreach ($user in $Email) {
113141
try {
114142
if ($Action -eq 'grant') {
115-
[void]$vault.GrantKeeperNSFFolderAccess($FolderUid, $user, $Role).GetAwaiter().GetResult()
116-
Write-Host "Granted '$Role' access to '$user' on folder '$FolderUid'." -ForegroundColor Green
143+
[void]$vault.GrantKeeperNSFFolderAccess($FolderUid, $user, $Role, $shareOptions).GetAwaiter().GetResult()
144+
$expireMsg = if ($shareOptions -and $shareOptions.Expiration) {
145+
" (expires $($shareOptions.Expiration.LocalDateTime.ToString('g')))"
146+
} else { '' }
147+
Write-Host "Granted '$Role' access to '$user' on folder '$FolderUid'$expireMsg." -ForegroundColor Green
117148
}
118149
else {
119150
[void]$vault.RevokeKeeperNSFFolderAccess($FolderUid, $user).GetAwaiter().GetResult()

PowerCommander/NsfRecordCommands.ps1

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,13 @@ function Set-KeeperNSFRecordAccess {
331331
.Parameter Role
332332
Access role for grant action: viewer (default), share-manager, content-manager,
333333
content-share-manager, full-manager.
334+
335+
.Parameter ExpireIn
336+
Optional. Share expiration period from now (e.g. 30d, 6mo, 1y, 24h, 30mi), integer minutes,
337+
or a TimeSpan. Same as Grant-KeeperRecordAccess.
338+
339+
.Parameter ExpireAt
340+
Optional. Absolute share expiration as ISO datetime (e.g. 2027-01-01T00:00:00Z).
334341
#>
335342
[CmdletBinding()]
336343
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
@@ -347,7 +354,15 @@ function Set-KeeperNSFRecordAccess {
347354

348355
[Parameter()]
349356
[ValidateSet('viewer', 'share-manager', 'content-manager', 'content-share-manager', 'full-manager')]
350-
[string] $Role = 'viewer'
357+
[string] $Role = 'viewer',
358+
359+
[Alias('expire-in')]
360+
[Parameter()]
361+
[System.Object] $ExpireIn,
362+
363+
[Alias('expire-at')]
364+
[Parameter()]
365+
[string] $ExpireAt
351366
)
352367

353368
try {
@@ -363,11 +378,27 @@ function Set-KeeperNSFRecordAccess {
363378
return
364379
}
365380

381+
$shareOptions = $null
382+
if ($Action -eq 'grant' -and ($ExpireIn -or $ExpireAt)) {
383+
try {
384+
$expirationDto = Get-ExpirationDate -ExpireIn $ExpireIn -ExpireAt $ExpireAt
385+
}
386+
catch {
387+
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
388+
return
389+
}
390+
$shareOptions = New-Object KeeperSecurity.Vault.SharedFolderRecordOptions
391+
$shareOptions.Expiration = $expirationDto
392+
}
393+
366394
foreach ($user in $Email) {
367395
try {
368396
if ($Action -eq 'grant') {
369-
[void]$vault.ShareKeeperNSFRecord($RecordUid, $user, $Role).GetAwaiter().GetResult()
370-
Write-Host "Granted '$Role' access to '$user' on record '$RecordUid'." -ForegroundColor Green
397+
[void]$vault.ShareKeeperNSFRecord($RecordUid, $user, $Role, $shareOptions).GetAwaiter().GetResult()
398+
$expireMsg = if ($shareOptions -and $shareOptions.Expiration) {
399+
" (expires $($shareOptions.Expiration.LocalDateTime.ToString('g')))"
400+
} else { '' }
401+
Write-Host "Granted '$Role' access to '$user' on record '$RecordUid'$expireMsg." -ForegroundColor Green
371402
}
372403
else {
373404
[void]$vault.UnshareKeeperNSFRecord($RecordUid, $user).GetAwaiter().GetResult()
@@ -881,21 +912,18 @@ function Remove-KeeperNSFRecord {
881912
begin {
882913
[KeeperSecurity.Vault.VaultOnline]$vault = getVault
883914
$removals = New-Object 'System.Collections.Generic.List[KeeperSecurity.Vault.KeeperNSFRecordRemoval]'
884-
$resolvedFolderUid = $null
915+
$folderHint = $null
885916

886917
if ($Folder) {
887918
[KeeperSecurity.Vault.FolderNode]$folderNode = $null
888919
if (-not $vault.TryResolveKeeperNSFFolder($Folder, [ref]$folderNode)) {
889920
Write-Error -Message "Keeper NSF folder `"$Folder`" was not found. Run Sync-Keeper or nsf-list first."
890921
return
891922
}
892-
$resolvedFolderUid = $folderNode.FolderUid
923+
$folderHint = $Folder
893924
}
894-
elseif ($Script:Context.CurrentFolder) {
895-
[KeeperSecurity.Vault.FolderNode]$currentFolder = $null
896-
if ($vault.TryResolveKeeperNSFFolder($Script:Context.CurrentFolder, [ref]$currentFolder)) {
897-
$resolvedFolderUid = $currentFolder.FolderUid
898-
}
925+
elseif ($Operation -ne 'owner-trash' -and $Script:Context.CurrentFolder) {
926+
$folderHint = $Script:Context.CurrentFolder
899927
}
900928

901929
$op = switch ($Operation) {
@@ -904,7 +932,7 @@ function Remove-KeeperNSFRecord {
904932
'unlink' { [KeeperSecurity.Vault.KeeperNSFRecordRemoveOperation]::Unlink }
905933
}
906934

907-
if ($op -eq [KeeperSecurity.Vault.KeeperNSFRecordRemoveOperation]::Unlink -and -not $resolvedFolderUid) {
935+
if ($op -eq [KeeperSecurity.Vault.KeeperNSFRecordRemoveOperation]::Unlink -and [string]::IsNullOrWhiteSpace($folderHint)) {
908936
Write-Error -Message "Folder context is required for unlink. Use -Folder or cd into a Keeper NSF folder."
909937
return
910938
}
@@ -918,14 +946,15 @@ function Remove-KeeperNSFRecord {
918946
continue
919947
}
920948

921-
$folderUid = $resolvedFolderUid
922-
if (-not $folderUid -and $op -ne [KeeperSecurity.Vault.KeeperNSFRecordRemoveOperation]::OwnerTrash) {
923-
$folderUids = @($vault.GetKeeperNSFFoldersForRecord($kdRecord.RecordUid))
924-
if ($folderUids.Count -eq 0) {
949+
[string]$folderUid = $null
950+
if (-not $vault.TryResolveKeeperNSFRecordRemovalFolder($kdRecord.RecordUid, $folderHint, $op, [ref]$folderUid)) {
951+
if ($Folder) {
952+
Write-Error -Message "Keeper NSF folder `"$Folder`" was not found. Run Sync-Keeper or nsf-list first."
953+
}
954+
else {
925955
Write-Error -Message "No folder context for record `"$name`". Use -Folder or -Operation owner-trash."
926-
continue
927956
}
928-
$folderUid = $folderUids[0]
957+
continue
929958
}
930959

931960
$removal = New-Object KeeperSecurity.Vault.KeeperNSFRecordRemoval
@@ -946,6 +975,15 @@ function Remove-KeeperNSFRecord {
946975
$previewResult = $vault.RemoveKeeperNSFRecords($removals, $true).GetAwaiter().GetResult()
947976
Write-KeeperNSFRemoveImpact -Response $previewResult.PreviewResponse
948977

978+
$previewErrors = @($previewResult.PreviewResponse.Results | Where-Object {
979+
$_.Error -and -not [string]::IsNullOrWhiteSpace($_.Error.Message)
980+
})
981+
if ($previewErrors.Count -gt 0) {
982+
Write-Host ""
983+
Write-Host "One or more records could not be previewed. Aborting." -ForegroundColor Yellow
984+
return
985+
}
986+
949987
try {
950988
[KeeperSecurity.Vault.VaultOnline]::ValidateRemoveResponse($previewResult.PreviewResponse, $false)
951989
}

PowerCommander/SharedFolderCommands.ps1

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,36 @@ function Get-KeeperSharedFolder {
1010
1111
.Parameter Filter
1212
Return matching shared folders only
13+
14+
.Parameter RoeEligible
15+
If set, only return shared folders eligible for rotate-on-expiration (contain a pamUser
16+
record with rotation configured).
1317
#>
1418
[CmdletBinding()]
1519
[OutputType([KeeperSecurity.Vault.SharedFolder[]])]
1620
Param (
1721
[string] $Uid,
18-
[string] $Filter
22+
[string] $Filter,
23+
[switch] $RoeEligible
1924
)
2025

2126
[KeeperSecurity.Vault.VaultOnline]$vault = getVault
2227

2328
[KeeperSecurity.Vault.SharedFolder] $sharedFolder = $null
2429
if ($Uid) {
2530
if ($vault.TryGetSharedFolder($uid, [ref]$sharedFolder)) {
26-
$sharedFolder
31+
if (-not $RoeEligible.IsPresent -or [KeeperSecurity.Vault.VaultShareExpirationExtensions]::SharedFolderHasPamUserWithRotation($vault, $sharedFolder.Uid)) {
32+
$sharedFolder
33+
}
2734
}
2835
}
2936
else {
30-
foreach ($sharedFolder in $vault.SharedFolders) {
37+
$folders = if ($RoeEligible.IsPresent) {
38+
[KeeperSecurity.Vault.VaultShareExpirationExtensions]::SearchRoeEligibleSharedFolders($vault, $Filter)
39+
} else {
40+
$vault.SharedFolders
41+
}
42+
foreach ($sharedFolder in $folders) {
3143
if ($Filter) {
3244
$match = $($sharedFolder.Uid, $sharedFolder.Name) | Select-String $Filter | Select-Object -First 1
3345
if (-not $match) {

0 commit comments

Comments
 (0)