Docs structure and initial content (#658)

* Clean up tree structure and add proper logo

* Proper logo files

* Initial docs

* Pick up new page after merging main

* Apply suggestions from code review

Some nits

Co-authored-by: Niraj Tolia <ntolia@users.noreply.github.com>

* Quash a bunch of Vale prose linter errors, warnings, and suggestions.

* PR Review feedback
* Simplified mount folders
* Cleaned up windows container
* Hid `latest` release tag

* Review feedback: Link to repo page

* Better arrow symbol

Co-authored-by: Niraj Tolia <ntolia@users.noreply.github.com>

* Clarify sentence

* Update README.md

* Reframing focus to M365

* More linting

* Use only MD files

Co-authored-by: Niraj Tolia <ntolia@users.noreply.github.com>
This commit is contained in:
Georgi Matev 2022-08-26 23:45:50 -04:00 committed by GitHub
parent 802001513f
commit 9f6b1bc1b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 432 additions and 118 deletions

View File

@ -1,22 +1,18 @@
# Corso
Corso is the first open-source tool that aims to assist admins with the
critical task of protecting SaaS service data. It provides a reliable, secure,
and efficient data protection engine. Admins decide where backup data is
stored and have the flexibility to execute backups of their desired service
through an intuitive interface. As Corso evolves, it can become a great
building block for more complex data protection workflows.
Corso is the first open-source tool that aims to assist IT admins with the critical task of protecting their
Microsoft 365 data. It provides a reliable, secure, and efficient data protection engine. Admins decide where backup
data is stored and have the flexibility to perform backups of their desired service through an intuitive interface.
As Corso evolves, it can become a great building block for more complex data protection workflows.
Corso is initially focused on protecting data in Microsoft 365 services such
as Exchange, OneDrive, SharePoint, and Teams. The goals is to expand coverage
for additional services, M365 or others, over time based on the interest and
needs of the community.
Corso supports supports M365 Exchange, OneDrive, SharePoint, and Teams. Coverage for additional services, possibly
even beyond M365, will expand based on the interest and needs of the community.
# Getting Started
## Getting Started
TODO - Link to the appropriate page in the published docs.
# Building Corso
## Building Corso
```sh
# Build a binary. Will be placed in bin/
@ -26,17 +22,17 @@ TODO - Link to the appropriate page in the published docs.
./build/build-container.sh
```
# Contribution Guidelines
## Contribution Guidelines
TODO
# Code of Conduct
## Code of Conduct
It is important that our community is inclusive and respectful of everyone.
It's important that our community is inclusive and respectful of everyone.
We ask that all Corso users and contributors take a few minutes to review our
[Code of Conduct](CODE_OF_CONDUCT.md)
# License
## License
TODO
`

View File

@ -1,3 +1,6 @@
{
"MD013": { "line_length": 120 }
"MD013": { "line_length": 120 },
"no-inline-html": {
"allowed_elements": [ "TOCInline", "br", "img" ]
},
}

View File

@ -34,11 +34,20 @@ This command generates static content into the `build` directory for integration
## Style and linting
```bash
# Lint all docs
make dockercheck
# Lint specific files and/or folders
make dockercheck VALE_TARGET="README.md docs/concepts"
```
This command will lint all Markdown files and check them for style issues using the Docker container
```bash
make check
```
This command will lint all Markdown files and check them for style issues.
Same as `make dockercheck` but runs locally. Requires `vale` to be installed.
## Documentation platform development

View File

@ -1,8 +0,0 @@
{
"label": "Concepts",
"position": 2,
"link": {
"type": "generated-index",
"description": "Core Corso Concepts."
}
}

View File

@ -1,41 +0,0 @@
---
sidebar_position: 1
---
# Repositories and configuration
## Object storage configuration
Corso stores all backup data in an object storage system. Corso supports Amazon Web
Services (AWS) S3, Google Cloud Storage (GCS), Azure Blob, and S3-compatible systems.
```mermaid
graph TD;
Corso-->ObjectStorage;
```
### Amazon S3 and S3-compatible systems
Corso needs the following permissions for AWS S3 and S3-compatible object storage systems:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetBucketLocation",
],
"Resource": [
"arn:aws:s3:::${BUCKET_NAME}",
"arn:aws:s3:::${BUCKET_NAME}/*"
]
}
]
}
```

View File

@ -0,0 +1,27 @@
---
description: "Core Corso concepts."
---
# Concepts
Before using Corso, it's important to familiarize yourself with some key concepts.
## Microsoft 365 concepts {#m365-concepts}
* **M365 Tenant** is typically associated with a unique domain (for example, `contoso.com`) and represents a dedicated
and logically segregated instance of the Microsoft 365 services plus associated data available to your organization.
* **M365 Service** refer to a cloud-applications available through the Microsoft 365 platform. Corso supports
backup and recovery for Exchange Online, OneDrive, SharePoint, and Teams.
* **Azure AD Application** represents an Azure AD digital identity/service principal and associated configuration which
define the accessible resources and permitted actions on these resources through the application. Corso uses an Azure AD
application to connect to your *M365 tenant* and transfer data during backup and restore operations.
## Corso concepts {#corso-concepts}
* **Repository** refers to the storage location where Corso securely and efficiently stores encrypted *backups* of your
*M365 Services* data. See [Repositories](/configuration/repos) for more information.
* **Backup** is a copy of your *M365 Services* data that can be restored if the original data is deleted, lost, or
corrupted. Corso performs backups incrementally; each backup only captures data that has changed between backup iterations.

View File

@ -0,0 +1,78 @@
---
description: "Connect to M365 Tenant"
---
# M365 access
To perform backup and restore operations, Corso requires access to your [M365 tenant](/concepts#m365-concepts)
through a properly configured [Azure AD application](/concepts#m365-concepts).
## Create Azure AD application
For the official documentation for adding an Azure AD Application and Service Principal using the Azure Portal see
[here](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal).
The following steps outline a simplified procedure for creating an Azure Ad application suitable for use with Corso.
1. **Create a new application**
Select **Azure Active Directory &#8594; App Registrations &#8594; New Registration**
<img src="/img/m365app_create_new.png" className="guideImages"/>
2. **Configure basic settings**
* Give the application a name
* Select **Accounts in this organizational directory only**
* Skip the **Redirect URI** option
<br/><img src="/img/m365app_configure.png" className="guideImages"/>
3. **Configure required permissions**
Select **App Permission** from the app management panel.
<img src="/img/m365app_permissions.png" className="guideImages"/>
The required permissions are as follows:
**TODO: Complete list of permissions**
| API / Permissions Name | Type |
|--|--|
| Permission 1 | Application |
| Permission 2 | Delegated |
4. **Grant admin consent**
<img src="/img/m365app_consent.png" className="guideImages"/>
## Export application credentials
Now that the Corso Azure AD application is configured, you need to capture as environment variables the information that
Corso will need to connect to the application.
### Tenant ID and client ID
To obtain these, select Overview from the app management panel and export the corresponding environment variables.
```bash
export AZURE_TENANT_ID=<Directory (tenent) ID for configured app>
export AZURE_CLIENT_ID=<Application (client) ID for configured app>
```
<img src="/img/m365app_ids.png" className="guideImages"/>
### Azure client secret
Lastly, you need to configure a client secret associated with the app using **Certificates & Secrets** from the app
management panel.
Click **New Client Secret** and follow the instructions to create a secret. After creating the secret, copy the secret
value right away because it's only available after creation. In the end, export the secret value as an environment
variable.
```bash
export AZURE_CLIENT_SECRET=<client secret value>
```
<img src="/img/m365app_secret.png" className="guideImages"/>

View File

@ -0,0 +1,73 @@
---
description: "Configure backup repository"
---
# Repositories
A Corso [repository](/concepts#corso-concepts) stores encrypted copies of your backup data. Repositories are
supported on the following object storage systems:
import TOCInline from '@theme/TOCInline';
<TOCInline toc={toc} maxHeadingLevel={2}/><br/>
:::note
Depending on community interest, Corso may support other object storage backends in the future.
:::
## Amazon S3
### Prerequisites
Before setting you your Corso S3 repository, the following prerequisites must be met:
* S3 bucket for the repository already exists. Corso won't create it for you.
* You have access to credentials for a user or an IAM role that represent the following permissions
**TODO: Verify if these permissions are correct? What about multi-part upload permissions?**
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetBucketLocation",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::<YOUR_BUCKET_NAME>",
"arn:aws:s3:::<YOUR_BUCKET_NAME>/*"
]
}
]
}
```
### Credential setup {#s3-creds-setup}
Corso supports the credential options offered by the Go SDK. For Full details, see the *Specifying Credentials*
section of the [official documentation](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html).
* **Environment variables** - set and export `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. If using temporary
credentials derived by assuming an IAM Role, you will also need `AWS_SESSION_TOKEN`.
* **Credentials file** - ensure that the credentials file is available to Corso (for example, may need to map it if
using Corso as a container). You may also want to set and export `AWS_PROFILE`, if not using the default profile, and
`AWS_SHARED_CREDENTIALS_FILE`, if not using the default file location. You can learn more about the AWS CLI
environment variables [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html).
### Initialize repository
Before first use, you need to initialize a Corso repository with `corso repo init s3`. See command details
[here](/cli/corso_repo_init_s3).
If a repository already exists, you can connect to it with `corso repo connect s3`. See command details
[here](/cli/corso_repo_connect_s3).

View File

@ -0,0 +1,3 @@
# Architecture
TODO

View File

@ -0,0 +1,3 @@
# Build from source
TODO

View File

@ -1,7 +1,3 @@
---
sidebar_position: 1
---
# Corso linters
Corso uses the golangci-lint GitHub action to run linters on every PR to `main`.
@ -79,7 +75,7 @@ This applies to golangci-lint v1.45.2 for the `gci` linter and is due to an impo
ordering issue. It occurs because imports in the file aren't grouped according
to the import rules for Corso. Corso code should have three distinct import
groups, system imports, third party imports, and imports of other Corso code
like below. The most likely cause of a `gci` lint error is a Corso import in the
like below. Typically the cause of a `gci` lint error is a Corso import in the
block for third party libraries.
```go

View File

@ -1,11 +1,15 @@
# Running tests locally
## Prerequisites
- Set `CORSO_PASSWORD` environment variable
```bash
export CORSO_PASSWORD=<some password>
```
- Set AWS credential (needed for tests that use S3) environment variables
```bash
export AWS_ACCESS_KEY_ID="...."
export AWS_SECRET_ACCESS_KEY="..."
@ -13,34 +17,39 @@
```
- Create a config file with the S3 bucket used for testing
```toml
bucket = '<bucket name>'
```
- Set `CORSO_TEST_CONFIG_FILE` to use the test config file
```bash
export CORSO_TEST_CONFIG_FILE=~/.corso_test.toml
```
- Set M365 Credentials environment variables
```bash
export TENANT_ID=<tenant>
export CLIENT_ID=<id>
export CLIENT_SECRET=<secret>
```
## Running Tests
## Running tests
Standard `go test ./...` will run unit tests
Integration style tests are configured to run only if enabled by setting the
appropriate ENV variable.
Integration style tests run when enabled by setting the appropriate environment variable.
e.g. `CORSO_CI_TESTS=true go test ./...`
For example, `CORSO_CI_TESTS=true go test ./...`
The complete list of environment constants is available at
`.../src/internal/tester/integration_runners.go`.
## Advanced Options
## Advanced options
- Use `CORSO_M356_TEST_USER_ID` to override the M365 user tests are run against
- To override the M365 user for tests, use `CORSO_M356_TEST_USER_ID`
```bash
export CORSO_M356_TEST_USER_ID="..."

83
docs/docs/install.md Normal file
View File

@ -0,0 +1,83 @@
# Installation
Corso releases are available using the following options:
import TOCInline from '@theme/TOCInline';
<TOCInline toc={toc} maxHeadingLevel={2}/><br/>
:::note
To maximize portability across platforms, Corso is available as a container image. In the future,
releases may also be available as operating system specific pre-built binaries.
In the meantime, if you want to run Corso as a binary, refer to the
[instructions on how to build from source](developers/build).
:::
## Docker image
To use Corso as a Docker image, you need to have [Docker installed](https://docs.docker.com/engine/install/)
on your machine.
### Docker command
To run the Corso container, it's recommended that you:
* Export [Corso key configuration environment variables](cli/corso_env) and add their names to an
[environment variables file](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file)
* Map a local directory to `/app/corso`. Corso will look for or create the `corso.toml` config file there. This will preserve
configuration across container runs. Corso will use the directoy for logs, if enabled.
To create the environment variables file, you can run the following.
```bash
# create an env vars file
$ cat <<EOF ~/.corso/corso.env
CORSO_PASSPHRASE
AZURE_TENANT_ID
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
EOF
```
:::note
Depending on your preferred method for passing AWS credentials, you may need to adapt the `AWS_` variables in the file.
See [AWS Credentials Setup](/configuration/repos##s3-creds-setup) for more details.
:::
The following command will list the Corso Exchange backups. You can adapt the folder mappings, container tag, and the command
as needed.
```bash
$ docker run --env-file ~/.corso/corso.env \
-v ~/.corso/corso:/app/corso \
corso/corso backup list exchange
```
### Available variants
The Corso image is available on DockerHub for the following architectures:
* Linux and Windows x86-64 - `amd64`
* ARM 64-bit - `arm64`
:::tip
For Windows, you can run the `amd64` container in
[Linux Mode](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-10-linux)
:::
The following tags are available:
* `:x.y.z` - A specific release build
* `:pre-release` - The most recent pre-release if newer that the latest stable release
* `:nightly` - The most recent unstable developer build
* `:SHA` - A specific build

View File

@ -1,33 +1,16 @@
---
sidebar_position: 1
---
# Introduction
# Corso introduction
## Overview
Discover **Corso in less than 5 minutes**.
Corso is the first open-source tool that aims to assist IT admins with the critical task of protecting their
Microsoft 365 data. It provides a reliable, secure, and efficient data protection engine. Admins decide where backup
data is stored and have the flexibility to perform backups of their desired service through an intuitive interface.
As Corso evolves, it can become a great building block for more complex data protection workflows.
Corso supports supports M365 Exchange, OneDrive, SharePoint, and Teams. Coverage for additional services, possibly
beyond M365, will expand based on the interest and needs of the community.
## Getting started
### What you'll need
- Docker
- A M365 account with the following permissions:
- _
## Running Corso
Corso with automatically run with the command:
```bash
docker run ...
```
You can type this command into Command Prompt, PowerShell, Terminal, or any other integrated terminal of your code editor.
## Your first M365 backup
To backup just your own personal data, run:
```bash
docker run ...
```
Follow the instructions in the [Installation](/install) and [Initial Configuration](/configuration) sections to setup
Corso and get it ready for first use. You can then go through the [Tutorial](/tutorial) section to see it in action.

78
docs/docs/tutorial.md Normal file
View File

@ -0,0 +1,78 @@
# Tutorial
In this tutorial you will perform your first backup followed by a restore.
## Prerequisites
* Docker is installed and Corso container is available (see [Installation](/install))
* Corso is connected to your M365 Tenant (see [M365 Access](/configuration/m365_access))
* Corso has initialized a backup repository (see [Repositories](/configuration/repos))
## Your first backup
Corso can do much more, but you can start by creating a backup of your Exchange mailbox.
To do this, you can run the following command:
```bash
$ docker run -e CORSO_PASSPHRASE \
--env-file ~/.corso/corso.env \
-v ~/.corso/config:/app/config \
-v ~/.corso/logs:/app/logs corso/corso:latest \
backup create exchange --user <your exchange email address>
```
:::note
Your first backup may take some time if your mailbox has many items so please be patient.
:::
**TODO:** Update ^^^ after Corso output from operations is finalized.
## Restore an email
Now lets explore how you can restore data from one of your backups.
You can see all Exchange backups available with the following command:
```bash
$ docker run -e CORSO_PASSPHRASE \
--env-file ~/.corso/corso.env \
-v ~/.corso/config:/app/config \
-v ~/.corso/logs:/app/logs corso/corso:latest \
backup list exchange --user <your exchange email address>
```
**TODO:** Update after Corso output from operations is finalized.
Select one of the available backups and search through its contents.
```bash
$ docker run -e CORSO_PASSPHRASE \
--env-file ~/.corso/corso.env \
-v ~/.corso/config:/app/config \
-v ~/.corso/logs:/app/logs corso/corso:latest \
backup details exchange \
--backup <id of your selected backup> \
--user <your exchange email address> \
--email-subject <portion of subject of email you want to recover>
```
The above should give you a list of any matching emails. Note the ID of the one you would like to
use for testing restore.
When you are ready to restore, use the following command:
```bash
$ docker run -e CORSO_PASSPHRASE \
--env-file ~/.corso/corso.env \
-v ~/.corso/config:/app/config \
-v ~/.corso/logs:/app/logs corso/corso:latest \
backup details exchange \
--backup <id of your selected backup> \
--user <your exchange email address> \
--email <id of your selected email>
```
You can now find the recovered email in a folder named "Corso_Restore_DD-MMM-YYYY_HH:MM:SS" in your mailbox.
You are now ready to explore the [Command Line Reference](cli) and try everything that Corso can do for you.

View File

@ -12,7 +12,7 @@ const config = {
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'throw',
favicon: 'img/corso.svg',
favicon: 'img/corso_logo.svg',
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
@ -26,6 +26,7 @@ const config = {
defaultLocale: 'en',
locales: ['en'],
},
staticDirectories: ['static', 'public'],
presets: [
[
@ -54,8 +55,8 @@ const config = {
title: 'Corso',
logo: {
alt: 'Corso Logo',
src: 'img/corso.svg',
srcDark: 'img/corso_white.svg',
src: '/img/corso_logo.svg',
srcDark: 'img/corso_logo_white.svg',
},
items: [
{

View File

@ -14,18 +14,32 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
docsSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
/*
tutorialSidebar: [
docsSidebar: [
'intro',
'install',
{
type: 'category',
label: 'Tutorial',
items: ['hello'],
label: 'Initial Configuration',
items: ['configuration/concepts', 'configuration/m365_access', 'configuration/repos'],
},
{
type: 'category',
label: 'Command Line Reference',
items: [
'cli/corso_repo_init_s3', 'cli/corso_repo_connect_s3',
'cli/corso_backup_create_exchange', 'cli/corso_backup_list_exchange', 'cli/corso_backup_details_exchange',
'cli/corso_restore_exchange',
]
},
{
type: 'category',
label: 'Developer Guide',
items: [
'developers/architecture', 'developers/build', 'developers/testing', 'developers/linters'
],
},
],
*/
};
module.exports = sidebars;

View File

@ -28,3 +28,9 @@
--ifm-color-primary-lightest: #4fddbf;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}
.guideImages {
max-width: 650px;
width: 100%;
border: 1px solid #80808029
}

1
docs/static/img/corso_logo.svg vendored Executable file
View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1350 1350"><defs><style>.cls-1{fill:#205eab;}</style></defs><path class="cls-1" d="M733.67,1251.47c-75.58,0-146.63-29.43-200.08-82.88L40,675,533.6,181.42c53.43-53.45,124.49-82.89,200.08-82.89s146.63,29.43,200.07,82.89l293.52,293.51c110.32,110.33,110.32,289.83,0,400.14l-293.52,293.52c-53.43,53.44-124.49,82.88-200.07,82.88ZM145.48,675l440.85,440.86c81.26,81.24,213.44,81.22,294.68,0l293.52-293.52c81.24-81.24,81.24-213.43,0-294.68L881.01,234.15c-39.36-39.36-91.68-61.04-147.33-61.04s-107.99,21.68-147.34,61.04L145.48,675Z"/><g><path class="cls-1" d="M1079.78,673.48l-14.74-92.16c-2.24-15.96-14.18-24.79-32.94-24.79l-109.95-.31c-17.69,0-30.7-8.84-32.94-24.79l-.38-2.62c-3.57-25.34-21.36-46.39-45.77-54.13l-147.73-54.08c-3.68-1.19-7.09-3.07-10.03-5.56-1.06-.9-1.78-2.14-2.17-3.48l-27.63-94.9c-.28-.96-.79-1.85-1.56-2.48-8.12-6.68-20.56-4.33-25.58,5.17l-54.49,122.05c-1.98,3.74-3.12,7.88-3.33,12.12l6.69,55.63c-.31,5.88-2.41,11.57-6,16.24l-108.67,108.07c-11.57,11.57-35.77,35.77-35.77,35.77l304.33,304.36,27.13-111.43c2.33-13.05,13.15-22.89,26.34-23.96l57.58-4.64c179.88-7.69,181.76-59.61,233.29-140.3,3-4.72,4.6-10.19,4.6-15.74,0-1.33-.1-2.69-.29-4.02Zm-236.75-89.74c-13.26,3.33-50.23,1.19-53.56-12.07-3.33-13.24,28.27-32.6,41.51-35.91,13.26-3.33,26.7,4.72,30.03,17.98,3.31,13.24-4.74,26.7-17.98,30.01Z"/><path class="cls-1" d="M781.88,435.5l-29.01-108.92c-.32-1.19-1.04-2.24-2.04-2.96-6.43-4.6-15.71-2.63-19.55,4.64l-36.4,75.39,87,31.84Z"/><path class="cls-1" d="M726.53,992.3l-1.88,7.71c-4.28,17.56-26.12,23.68-38.91,10.9l-274.22-274.22-26.1-26.1,29.7-29.7,26.1,26.1,285.31,285.31Z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

1
docs/static/img/corso_logo_white.svg vendored Executable file
View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1350 1350"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M733.67,1251.47c-75.58,0-146.63-29.43-200.08-82.88L40,675,533.6,181.42c53.43-53.45,124.49-82.89,200.08-82.89s146.63,29.43,200.07,82.89l293.52,293.51c110.32,110.33,110.32,289.83,0,400.14l-293.52,293.52c-53.43,53.44-124.49,82.88-200.07,82.88ZM145.48,675l440.85,440.86c81.26,81.24,213.44,81.22,294.68,0l293.52-293.52c81.24-81.24,81.24-213.43,0-294.68L881.01,234.15c-39.36-39.36-91.68-61.04-147.33-61.04s-107.99,21.68-147.34,61.04L145.48,675Z"/><g><path class="cls-1" d="M1079.78,673.48l-14.74-92.16c-2.24-15.96-14.18-24.79-32.94-24.79l-109.95-.31c-17.69,0-30.7-8.84-32.94-24.79l-.38-2.62c-3.57-25.34-21.36-46.39-45.77-54.13l-147.73-54.08c-3.68-1.19-7.09-3.07-10.03-5.56-1.06-.9-1.78-2.14-2.17-3.48l-27.63-94.9c-.28-.96-.79-1.85-1.56-2.48-8.12-6.68-20.56-4.33-25.58,5.17l-54.49,122.05c-1.98,3.74-3.12,7.88-3.33,12.12l6.69,55.63c-.31,5.88-2.41,11.57-6,16.24l-108.67,108.07c-11.57,11.57-35.77,35.77-35.77,35.77l304.33,304.36,27.13-111.43c2.33-13.05,13.15-22.89,26.34-23.96l57.58-4.64c179.88-7.69,181.76-59.61,233.29-140.3,3-4.72,4.6-10.19,4.6-15.74,0-1.33-.1-2.69-.29-4.02Zm-236.75-89.74c-13.26,3.33-50.23,1.19-53.56-12.07-3.33-13.24,28.27-32.6,41.51-35.91,13.26-3.33,26.7,4.72,30.03,17.98,3.31,13.24-4.74,26.7-17.98,30.01Z"/><path class="cls-1" d="M781.88,435.5l-29.01-108.92c-.32-1.19-1.04-2.24-2.04-2.96-6.43-4.6-15.71-2.63-19.55,4.64l-36.4,75.39,87,31.84Z"/><path class="cls-1" d="M726.53,992.3l-1.88,7.71c-4.28,17.56-26.12,23.68-38.91,10.9l-274.22-274.22-26.1-26.1,29.7-29.7,26.1,26.1,285.31,285.31Z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/static/img/m365app_configure.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

BIN
docs/static/img/m365app_consent.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 KiB

BIN
docs/static/img/m365app_create_new.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

BIN
docs/static/img/m365app_ids.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 KiB

BIN
docs/static/img/m365app_permissions.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 KiB

BIN
docs/static/img/m365app_secret.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB