diff --git a/deploy/create-aadapp-cli.ps1 b/deploy/create-aadapp-cli.ps1
new file mode 100644
index 0000000..b83fc95
--- /dev/null
+++ b/deploy/create-aadapp-cli.ps1
@@ -0,0 +1,33 @@
+# Azure CLI must be installed
+# https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-cli
+# User must be able to create apps and consent (Global Admin, ...)
+
+$appName = "dev-GKMM-msteamsbackup-app"; #Change for example GKMM to your tenant
+$servicePrincipalName = "Microsoft Graph";
+$servicePrincipalNameOauth2Permissions = @("Channel.ReadBasic.All", "ChannelMember.Read.All", "ChannelMessage.Read.All", "ChannelSettings.Read.All", "Group.Read.All", "GroupMember.Read.All", "Team.ReadBasic.All", "TeamMember.Read.All", "TeamSettings.Read.All", "TeamsTab.Read.All");
+
+az login --use-device-code --allow-no-subscriptions
+
+$servicePrincipalId = az ad sp list --filter "displayname eq '$servicePrincipalName'" --query '[0].appId' | ConvertFrom-Json
+
+$reqGraph = @{
+ resourceAppId = $servicePrincipalId
+ resourceAccess = @()
+}
+
+(az ad sp show --id $servicePrincipalId --query oauth2Permissions | ConvertFrom-Json) | ? { $_.value -in $servicePrincipalNameOauth2Permissions} | % {
+ $permission = $_
+
+ $delPermission = @{
+ id = $permission.Id
+ type = "Scope"
+ }
+ $reqGraph.resourceAccess += $delPermission
+}
+
+Set-Content ./required_resource_accesses.json -Value ("[" + ($reqGraph | ConvertTo-Json) + "]")
+$newapp = az ad app create --display-name $appName --available-to-other-tenants false --native-app true --required-resource-accesses `@required_resource_accesses.json | ConvertFrom-Json
+az ad app permission admin-consent --id $newapp.appId
+
+"ClientId: " + $newapp.appId;
+"TenantId: " + (az account show | ConvertFrom-Json).tenantId;
\ No newline at end of file
diff --git a/deploy/create-aadapp.ps1 b/deploy/create-aadapp.ps1
new file mode 100644
index 0000000..a59e9f9
--- /dev/null
+++ b/deploy/create-aadapp.ps1
@@ -0,0 +1,31 @@
+# Requires AzureADPreview Module;
+# Install-Module AzureADPreview
+# User must be able to create apps and consent (Global Admin, ...)
+
+$appName = "dev-GKMM-msteamsbackup-app"; #Change for example GKMM to your tenant
+$servicePrincipalName = "Microsoft Graph";
+$servicePrincipalNameOauth2Permissions = @("Channel.ReadBasic.All", "ChannelMember.Read.All", "ChannelMessage.Read.All", "ChannelSettings.Read.All", "Group.Read.All", "GroupMember.Read.All", "Team.ReadBasic.All", "TeamMember.Read.All", "TeamSettings.Read.All", "TeamsTab.Read.All");
+
+# login
+Connect-AzureAD;
+
+# Get MS Graph
+$servicePrincipal = Get-AzureADServicePrincipal -All $true | ? { $_.DisplayName -eq $servicePrincipalName };
+
+# Thanks http://blog.octavie.nl/index.php/2017/09/19/create-azure-ad-app-registration-with-powershell-part-2
+$reqGraph = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess";
+$reqGraph.ResourceAppId = $servicePrincipal.AppId;
+
+$servicePrincipal.Oauth2Permissions | ? { $_.Value -in $servicePrincipalNameOauth2Permissions} | % {
+ $permission = $_
+ $delPermission = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $permission.Id,"Scope" #delegate permission (oauth) are always "Scope"
+ $reqGraph.ResourceAccess += $delPermission
+}
+
+New-AzureADApplication -DisplayName $appName -AvailableToOtherTenants:$false -PublicClient:$true -RequiredResourceAccess $reqGraph;
+$newapp = Get-AzureADApplication -SearchString $appName;
+"ClientId: " + $newapp.AppId;
+"TenantId: " + (Get-AzureADTenantDetail).ObjectId;
+
+"TODO: Consent in portal";
+"Check AAD app: https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/CallAnAPI/appId/" + $newapp.AppId + "/objectId/" + $newapp.ObjectId + "/isMSAApp/";
\ No newline at end of file
diff --git a/deploy/publish-BackupConsole.ps1 b/deploy/publish-BackupConsole.ps1
new file mode 100644
index 0000000..aa32ea8
--- /dev/null
+++ b/deploy/publish-BackupConsole.ps1
@@ -0,0 +1,29 @@
+#Build release
+$corePathToProject = "..\src\BackupConsole";
+$configNames = @("Release");
+
+foreach($configName in $configNames){
+ $configName;
+ $publishLocation = ".\$configName-output";
+ $publishLocationApp = $publishLocation + "\M365.TeamsBackup.BackupConsole.exe";
+
+
+ dotnet publish $corePathToProject --configuration $configName --output $publishLocation;
+
+ Remove-Item "$publishLocation/appsettings.Development.json";
+ Remove-Item "$publishLocation/appsettings.Production.json";
+
+ if (Test-Path $publishLocationApp){
+
+ if ((Test-Path $configName) -eq $false){
+ mkdir $configName;
+ }
+
+ $version2publish = [System.Diagnostics.FileVersionInfo]::GetVersionInfo((Get-Location).ToString() + $publishLocationApp).FileVersion.ToString().Replace(".", "-");
+
+ $thisZipVersion = ".\" + $configName + "\M365.TeamsBackup.BackupConsole-V-" + $version2publish + "-" + $configName + ".zip";
+
+ Compress-Archive ($publishLocation + "\*") $thisZipVersion -CompressionLevel Fastest;
+ Remove-Item $publishLocation -Recurse:$true
+ }
+}
\ No newline at end of file
diff --git a/deploy/publish-BackupToHtmlConsole.ps1 b/deploy/publish-BackupToHtmlConsole.ps1
new file mode 100644
index 0000000..ff94bfb
--- /dev/null
+++ b/deploy/publish-BackupToHtmlConsole.ps1
@@ -0,0 +1,29 @@
+#Build release
+$corePathToProject = "..\src\BackupToHtmlConsole";
+$configNames = @("Release");
+
+foreach($configName in $configNames){
+ $configName;
+ $publishLocation = ".\$configName-output";
+ $publishLocationApp = $publishLocation + "\M365.TeamsBackup.BackupToHtmlConsole.exe";
+
+
+ dotnet publish $corePathToProject --configuration $configName --output $publishLocation;
+
+ Remove-Item "$publishLocation/appsettings.Development.json";
+ Remove-Item "$publishLocation/appsettings.Production.json";
+
+ if (Test-Path $publishLocationApp){
+
+ if ((Test-Path $configName) -eq $false){
+ mkdir $configName;
+ }
+
+ $version2publish = [System.Diagnostics.FileVersionInfo]::GetVersionInfo((Get-Location).ToString() + $publishLocationApp).FileVersion.ToString().Replace(".", "-");
+
+ $thisZipVersion = ".\" + $configName + "\M365.TeamsBackup.BackupToHtmlConsole-V-" + $version2publish + "-" + $configName + ".zip";
+
+ Compress-Archive ($publishLocation + "\*") $thisZipVersion -CompressionLevel Fastest;
+ Remove-Item $publishLocation -Recurse:$true
+ }
+}
\ No newline at end of file
diff --git a/src/BackupConsole/BackupConsole.csproj b/src/BackupConsole/BackupConsole.csproj
index 443483d..3fca044 100644
--- a/src/BackupConsole/BackupConsole.csproj
+++ b/src/BackupConsole/BackupConsole.csproj
@@ -6,7 +6,7 @@
M365.TeamsBackup.BackupConsole
M365.TeamsBackup.BackupConsole
Marco Scheel
- 0.1.3
+ 0.1.4
M365.TeamsBackup
Backup from MS Graph Beta to Local JSON
@@ -33,4 +33,10 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/src/BackupConsole/Properties/launchSettings.json b/src/BackupConsole/Properties/launchSettings.json
index a68c905..2182415 100644
--- a/src/BackupConsole/Properties/launchSettings.json
+++ b/src/BackupConsole/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"BackupConsole": {
"commandName": "Project",
- "commandLineArgs": "--environment Production"
+ "commandLineArgs": "--environment Development"
}
}
}
\ No newline at end of file
diff --git a/src/BackupConsole/appsettings.Development.json b/src/BackupConsole/appsettings.Development.json
index 7d12e85..9c84738 100644
--- a/src/BackupConsole/appsettings.Development.json
+++ b/src/BackupConsole/appsettings.Development.json
@@ -8,14 +8,14 @@
},
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
- "ClientId": "12c9d807-90dd-42d8-abb3-b5f15a03d492",
+ "ClientId": "fdc12731-7742-4c3d-a3ab-f3b358ba2e09",
"TenantId": "052c8489-1e3c-450e-9b79-233d8604e40a",
- "ReplyUri": "msal12c9d807-90dd-42d8-abb3-b5f15a03d492://auth",
"Scope": [ "https://graph.microsoft.com/.default" ]
},
"M365": {
"Backup": {
"Path": "C:\\Code\\M365.TeamsBackup\\data\\development",
+ "ShouldZip": true,
"JsonWriteIndented": true,
"TeamId": "872265e1-0c5a-48ea-9355-0710869db8cb"
}
diff --git a/src/BackupConsole/appsettings.Production.json b/src/BackupConsole/appsettings.Production.json
index 77bd790..073c422 100644
--- a/src/BackupConsole/appsettings.Production.json
+++ b/src/BackupConsole/appsettings.Production.json
@@ -10,13 +10,13 @@
"Instance": "https://login.microsoftonline.com",
"ClientId": "4c50ca04-1ecf-4a02-8ac0-c8698a818701",
"TenantId": "cb9543bb-9168-4dc6-b17f-766487518a6a",
- "ReplyUri": "msal4c50ca04-1ecf-4a02-8ac0-c8698a818701://auth",
"Scope": [ "https://graph.microsoft.com/.default" ]
},
"M365": {
"Backup": {
"Path": "C:\\Code\\M365.TeamsBackup\\data\\production",
"JsonWriteIndented": false,
+ "ShouldZip": true,
"TeamId": "8b04f653-e2ba-4b57-92b7-3d1247073927"
}
}
diff --git a/src/BackupConsole/appsettings.json b/src/BackupConsole/appsettings.json
index 5166e3d..272a3d3 100644
--- a/src/BackupConsole/appsettings.json
+++ b/src/BackupConsole/appsettings.json
@@ -9,13 +9,13 @@
"Instance": "https://login.microsoftonline.com",
"ClientId": "YOUR AAD CLIENT ID",
"TenantId": "YOUR AAD TENANT ID",
- "ReplyUri": "YOUR AAD APP REPLY URI",
"Scope": [ "https://graph.microsoft.com/.default" ]
},
"M365": {
"Backup": {
"Path": "C:\\M365.TeamsBackup\\data",
"JsonWriteIndented": false,
+ "ShouldZip": false,
"TeamId": "YOUR TEAM ID TO BACKUP"
}
}
diff --git a/src/BackupToHtmlConsole/BackupToHtmlConsole.csproj b/src/BackupToHtmlConsole/BackupToHtmlConsole.csproj
index 301ad62..a807937 100644
--- a/src/BackupToHtmlConsole/BackupToHtmlConsole.csproj
+++ b/src/BackupToHtmlConsole/BackupToHtmlConsole.csproj
@@ -5,7 +5,7 @@
net5.0
M365.TeamsBackup.BackupToHtmlConsole
M365.TeamsBackup.BackupToHtmlConsole
- 0.1.3
+ 0.1.4
Marco Scheel
M365.TeamsBackup
Convert an existing JSON based backup to HTML
@@ -33,4 +33,10 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/src/BackupToHtmlConsole/Properties/launchSettings.json b/src/BackupToHtmlConsole/Properties/launchSettings.json
index d515a22..d85d5db 100644
--- a/src/BackupToHtmlConsole/Properties/launchSettings.json
+++ b/src/BackupToHtmlConsole/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"BackupToHtmlConsole": {
"commandName": "Project",
- "commandLineArgs": "--environment Production"
+ "commandLineArgs": "--environment Development"
}
}
}
\ No newline at end of file
diff --git a/src/BackupToHtmlConsole/appsettings.Development.json b/src/BackupToHtmlConsole/appsettings.Development.json
index f7f68c8..805b3cb 100644
--- a/src/BackupToHtmlConsole/appsettings.Development.json
+++ b/src/BackupToHtmlConsole/appsettings.Development.json
@@ -11,7 +11,7 @@
"SourcePath": "C:\\Code\\M365.TeamsBackup\\data\\development",
"TargetPath": "C:\\Code\\M365.TeamsBackup\\data\\development-html",
"TemplateFile": "C:\\Code\\M365.TeamsBackup\\template\\template.html",
- "UseInlineImages": true,
+ "UseInlineImages": false,
"CreateSingleHtmlForMessage": true
}
}
diff --git a/src/Core/Config/AzureAD.cs b/src/Core/Config/AzureAD.cs
index 9e946fe..629c737 100644
--- a/src/Core/Config/AzureAD.cs
+++ b/src/Core/Config/AzureAD.cs
@@ -11,7 +11,6 @@ public class AzureAd
public string Instance { get; set; }
public string ClientId { get; set; }
public string TenantId { get; set; }
- public string ReplyUri { get; set; }
public string[] Scope { get; set; }
}
}
diff --git a/src/Core/Config/Backup.cs b/src/Core/Config/Backup.cs
index aab5858..673089b 100644
--- a/src/Core/Config/Backup.cs
+++ b/src/Core/Config/Backup.cs
@@ -1,4 +1,5 @@
-using System;
+using Microsoft.Graph;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -11,6 +12,7 @@ namespace M365.TeamsBackup.Core.Config
public class Backup
{
public string Path { get; set; }
+ public bool ShouldZip { get; set; }
public string TeamId { get; set; }
public bool JsonWriteIndented { get; set; }
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index 04f290d..3b7a516 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -4,18 +4,18 @@
net5.0
M365.TeamsBackup.Core
M365.TeamsBackup.Core
- 0.1.3
+ 0.1.4
Marco Scheel
M365.TeamsBackup
-
+
-
+
diff --git a/src/Core/Data/HtmlTeamChannelMessage.cs b/src/Core/Data/HtmlTeamChannelMessage.cs
index 6f96101..051c57d 100644
--- a/src/Core/Data/HtmlTeamChannelMessage.cs
+++ b/src/Core/Data/HtmlTeamChannelMessage.cs
@@ -192,6 +192,8 @@ private void GetHtmlForPost(HtmlNode threadNode, ChatMessage message)
}
System.IO.File.Copy(blobFileName, outFilename, true);
+ System.IO.File.SetCreationTime(outFilename, message.CreatedDateTime.Value.DateTime);
+ System.IO.File.SetLastWriteTime(outFilename, message.CreatedDateTime.Value.DateTime);
imgNode.SetAttributeValue("src", $"./img/{System.IO.Path.GetFileName(outFilename)}");
}
diff --git a/src/Core/Data/MgTeam.cs b/src/Core/Data/MgTeam.cs
index e79ff46..a8f487d 100644
--- a/src/Core/Data/MgTeam.cs
+++ b/src/Core/Data/MgTeam.cs
@@ -111,11 +111,18 @@ public static string GetBackupPath(string root, string teamId)
System.IO.Directory.CreateDirectory(fullpath);
return fullpath;
}
+
public static string GetBackupTeamFile(string root, string teamId)
{
var fullpath = System.IO.Path.Combine(GetBackupPath(root, teamId), "team.json");
return fullpath;
}
+ public static string GetBackupTeamZipFile(string root, string teamId)
+ {
+ var fullpath = System.IO.Path.Combine(root, $"{teamId}.zip");
+ return fullpath;
+ }
+
public static string GetBackupTeamMembersFile(string root, string teamId)
{
var fullpath = System.IO.Path.Combine(GetBackupPath(root, teamId), "team.members.json");
diff --git a/src/Core/Services/BackupFromGraphService.cs b/src/Core/Services/BackupFromGraphService.cs
index 6923360..efb1d22 100644
--- a/src/Core/Services/BackupFromGraphService.cs
+++ b/src/Core/Services/BackupFromGraphService.cs
@@ -34,8 +34,10 @@ public BackupFromGraphService(ILogger logger, ILogger