Kavita/API/Data/MigrateConfigFiles.cs
Joseph Milazzo efb527035d
Account Email Support (#1000)
* Moved the Server Settings out into a button on nav header

* Refactored Mange Users page to the new design (skeleton). Implemented skeleton code for Invite User.

* Hashed out more of the code, but need to move all the email code to a Kavita controlled API server due to password credentials.

* Cleaned up some warnings

* When no user exists for an api key in Plugin controller, throw 401.

* Hooked in the ability to check if the Kavita instance can be accessed externally so we can determine if the user can invite or not.

* Hooked up some logic if the user's server isn't accessible, then default to old flow

* Basic flow is working for confirm email. Needs validation, error handling, etc.

* Refactored Password validation to account service

* Cleaned up the code in confirm-email to work much better.

* Refactored the login page to have a container functionality, so we can reuse the styles on multiple pages (registration pages). Hooked up the code for confirm email.

* Messy code, but making progress. Refactored Register to be used only for first time user registration. Added a new register component to handle first time flow only.

* Invite works much better, still needs a bit of work for non-accessible server setup. Started work on underlying manage users page to meet new design.

* Changed (you) to a star to indicate who you're logged in as.

* Inviting a user is now working and tested fully.

* Removed the register member component as we now have invite and confirm components.

* Editing a user is now working. Username change and Role/Library access from within one screen. Email changing is on hold.

* Cleaned up code for edit user and disabled email field for now.

* Cleaned up the code to indicate changing a user's email is not possible.

* Implemented a migration for existing accounts so they can validate their emails and still login.

* Change url for email server

* Implemented the ability to resend an email confirmation code (or regenerate for non accessible servers). Fixed an overflow on the confirm dialog.

* Took care of some code cleanup

* Removed 3 db calls from cover refresh and some misc cleanup

* Fixed a broken test
2022-01-30 14:45:57 -08:00

169 lines
5.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using API.Services;
using Kavita.Common;
namespace API.Data
{
/// <summary>
/// A Migration to migrate config related files to the config/ directory for installs prior to v0.4.9.
/// </summary>
public static class MigrateConfigFiles
{
private static readonly List<string> LooseLeafFiles = new List<string>()
{
"appsettings.json",
"appsettings.Development.json",
"kavita.db",
};
private static readonly List<string> AppFolders = new List<string>()
{
"covers",
"stats",
"logs",
"backups",
"cache",
"temp"
};
/// <summary>
/// In v0.4.8 we moved all config files to config/ to match with how docker was setup. This will move all config files from current directory
/// to config/
/// </summary>
public static void Migrate(bool isDocker, IDirectoryService directoryService)
{
Console.WriteLine("Checking if migration to config/ is needed");
if (isDocker)
{
if (Configuration.LogPath.Contains("config"))
{
Console.WriteLine("Migration to config/ not needed");
return;
}
Console.WriteLine(
"Migrating files from pre-v0.4.8. All Kavita config files are now located in config/");
CopyAppFolders(directoryService);
DeleteAppFolders(directoryService);
UpdateConfiguration();
Console.WriteLine("Migration complete. All config files are now in config/ directory");
return;
}
if (new FileInfo(Configuration.AppSettingsFilename).Exists)
{
Console.WriteLine("Migration to config/ not needed");
return;
}
Console.WriteLine(
"Migrating files from pre-v0.4.8. All Kavita config files are now located in config/");
Console.WriteLine($"Creating {directoryService.ConfigDirectory}");
directoryService.ExistOrCreate(directoryService.ConfigDirectory);
try
{
CopyLooseLeafFiles(directoryService);
CopyAppFolders(directoryService);
// Then we need to update the config file to point to the new DB file
UpdateConfiguration();
}
catch (Exception)
{
Console.WriteLine("There was an exception during migration. Please move everything manually.");
return;
}
// Finally delete everything in the source directory
Console.WriteLine("Removing old files");
DeleteLooseFiles(directoryService);
DeleteAppFolders(directoryService);
Console.WriteLine("Removing old files...DONE");
Console.WriteLine("Migration complete. All config files are now in config/ directory");
}
private static void DeleteAppFolders(IDirectoryService directoryService)
{
foreach (var folderToDelete in AppFolders)
{
if (!new DirectoryInfo(Path.Join(Directory.GetCurrentDirectory(), folderToDelete)).Exists) continue;
directoryService.ClearAndDeleteDirectory(Path.Join(Directory.GetCurrentDirectory(), folderToDelete));
}
}
private static void DeleteLooseFiles(IDirectoryService directoryService)
{
var configFiles = LooseLeafFiles.Select(file => new FileInfo(Path.Join(Directory.GetCurrentDirectory(), file)))
.Where(f => f.Exists);
directoryService.DeleteFiles(configFiles.Select(f => f.FullName));
}
private static void CopyAppFolders(IDirectoryService directoryService)
{
Console.WriteLine("Moving folders to config");
foreach (var folderToMove in AppFolders)
{
if (new DirectoryInfo(Path.Join(directoryService.ConfigDirectory, folderToMove)).Exists) continue;
try
{
directoryService.CopyDirectoryToDirectory(
Path.Join(directoryService.FileSystem.Directory.GetCurrentDirectory(), folderToMove),
Path.Join(directoryService.ConfigDirectory, folderToMove));
}
catch (Exception)
{
/* Swallow Exception */
}
}
Console.WriteLine("Moving folders to config...DONE");
}
private static void CopyLooseLeafFiles(IDirectoryService directoryService)
{
var configFiles = LooseLeafFiles.Select(file => new FileInfo(Path.Join(directoryService.FileSystem.Directory.GetCurrentDirectory(), file)))
.Where(f => f.Exists);
// First step is to move all the files
Console.WriteLine("Moving files to config/");
foreach (var fileInfo in configFiles)
{
try
{
fileInfo.CopyTo(Path.Join(directoryService.ConfigDirectory, fileInfo.Name));
}
catch (Exception)
{
/* Swallow exception when already exists */
}
}
Console.WriteLine("Moving files to config...DONE");
}
private static void UpdateConfiguration()
{
Console.WriteLine("Updating appsettings.json to new paths");
Configuration.DatabasePath = "config//kavita.db";
Configuration.LogPath = "config//logs/kavita.log";
Console.WriteLine("Updating appsettings.json to new paths...DONE");
}
}
}