{"id":30358972,"url":"https://github.com/linux-alex/graphlink","last_synced_at":"2025-08-19T11:16:25.633Z","repository":{"id":304734807,"uuid":"1019779400","full_name":"Linux-Alex/GraphLink","owner":"Linux-Alex","description":"GraphLink is a secure .NET API gateway for Microsoft 365 mailboxes, providing controlled email access with API key authentication and granular permissions for sending, reading, and filtering messages.","archived":false,"fork":false,"pushed_at":"2025-07-22T04:08:40.000Z","size":10775,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-22T06:39:04.945Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Linux-Alex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-14T21:28:40.000Z","updated_at":"2025-07-22T04:08:44.000Z","dependencies_parsed_at":"2025-07-15T02:21:43.117Z","dependency_job_id":"35e5e3d0-ca1c-49d3-9eac-babc9b24c02d","html_url":"https://github.com/Linux-Alex/GraphLink","commit_stats":null,"previous_names":["linux-alex/graphlink"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Linux-Alex/GraphLink","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Linux-Alex%2FGraphLink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Linux-Alex%2FGraphLink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Linux-Alex%2FGraphLink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Linux-Alex%2FGraphLink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Linux-Alex","download_url":"https://codeload.github.com/Linux-Alex/GraphLink/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Linux-Alex%2FGraphLink/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271143398,"owners_count":24706346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-19T11:16:24.039Z","updated_at":"2025-08-19T11:16:25.623Z","avatar_url":"https://github.com/Linux-Alex.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📬 GraphLink\n\n**GraphLink** is a lightweight .NET Core Web API that connects to Microsoft 365 email accounts using the Microsoft Graph API.\n\n\u003e 🔐 Authenticated via API key  \n\u003e 💌 Supports sending \u0026 reading emails  \n\u003e 📎 Attachments supported  \n\u003e 🛡️ Recipient filtering included  \n\u003e 🚀 Easily configurable via `appsettings.json`\n\n---\n\n## 🌐 Endpoints\n\n### ✅ `GET /api/emails/{userEmail}`  \nRead incoming emails from the user's inbox (with optional filters).\n\n| Query Param | Type     | Description |\n|-------------|----------|-------------|\n| `top`       | `int`    | Number of messages (default: 10) |\n| `folder`    | `string` | Folder name (default: \"Inbox\") |\n| `fromDate`  | `string` | ISO 8601 date to filter from |\n\n### ✅ `POST /api/emails/{userEmail}`  \nSend an email from a configured M365 account.\n\n**Body:**\n```json\n{\n  \"To\": \"someone@example.com\",\n  \"Cc\": \"cc@example.com\",\n  \"Bcc\": \"bcc@example.com\",\n  \"Subject\": \"Hello World!\",\n  \"Body\": \"This is the email content.\",\n  \"Attachments\": [\n    {\n      \"Name\": \"report.pdf\",\n      \"ContentType\": \"application/pdf\",\n      \"Base64Content\": \"JVBERi0xLjcKJc...\"\n    }\n  ]\n}\n```\n\n## 🔑 API Key\nAll endpoints require an API key in the header:\n\n```makefile\nX-API-KEY: supersecureapikey123!\n```\n\n\u003e 🔐 The key is configured in `appsettings.json` (change it in production).\n\n\n## ⚙️ Configuration\n\nYou need to register a Microsoft 365 app and the GraphLink with it:\n\n### 🛠️ Microsoft 365 App Registration Guide\n\n1. Create App Registration in Azure AD\n    1. Go to [Azure Portal](https://portal.azure.com/) and login\n    2. Search for **App registrations** and click on **+ New registration**\n    3. Enter details:\n        - Name: `GraphLink Service`\n        - Supported account types: **Accounts in this organizational directory only (#### only - Single Tenant)**\n        - Redirect URI: `http://localhost` (Web platform)\n    4. Submit with a click on the button **Register**\n2. Configure API Permissions\n    1. In your new app registration, go to **Manage** \u003e **API permissions**\n    2. Click on **Add a permission**, choose **Microsoft Graph** and **Application permissions**\n    3. Search and add these permissions:\n        - `Mail.Read`\n        - `Mail.ReadWrite`\n        - `Mail.Send`\n    4. Submit with a click on the button **Add permissions**\n    5. In the **Configure permissions** region, click on the **✓ Grand admin consent for ####** and confirm to add the admin permissions for the task\n3. Create Client Secret\n    1. In the registrated app, go to **Manage** \u003e **Certificates \u0026 secrets**\n    2. Click on **New client secret**\n    3. Add a description (like \"GraphLink Secret\"), expiration and click on **Add**\n    4. **Copy the secret value**, cause you won't see it again\n4. Restrict Access to Specific Users (using Powershell):\n    1. Install Microsoft Graph PowerShell SDK:\n        ```ps\n        Install-Module Microsoft.Graph -Scope CurrentUser\n        ```\n        If it prompts about an untrusted repository, choose **A** (Yes to All).\n    2. Connect to Microsoft Graph:\n        ```ps\n        Connect-MgGraph -Scopes \"User.Read.All\", \"Application.Read.All\", \"AppRoleAssignment.ReadWrite.All\", \"Directory.ReadWrite.All\"\n        ```\n    3. Get your app's service principal:\n        ```ps\n        $appName = \"GraphLink Service\"\n        $sp = Get-MgServicePrincipal -Filter \"displayName eq '$appName'\"\n        ```\n\n        If your not sure about the correct name, you can check the found app using:\n        ```ps\n        echo $sp\n        ```\n        and you should see something like this, if there is an app found (or nothing if not):\n        ```\n        DisplayName       Id                                   AppId                                SignInAudience ServicePrincipalType\n        -----------       --                                   -----                                -------------- --------------------\n        GraphLink Service b9eaaa12-####-####-####-############ 9dfa2cc9-####-####-####-############ AzureADMyOrg   Application\n        ```\n    4. Get user to restrict access to:\n        ```ps\n        $user = Get-MgUser -UserId \"allowed.user@yourdomain.com\"\n        ```\n    5. Assign app to specific user only:\n        ```ps\n        New-MgServicePrincipalAppRoleAssignment `\n            -ServicePrincipalId $sp.Id `\n            -PrincipalId $user.Id `\n            -ResourceId $sp.Id `\n            -AppRoleId \"00000000-0000-0000-0000-000000000000\" |\n            Format-List\n        ```\n    6. Verify the assignment:\n        ```ps\n        Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $sp.Id |\n            Where-Object { $_.PrincipalId -eq $user.Id } |\n            Select-Object Id, AppRoleId, PrincipalDisplayName, ResourceDisplayName\n        ```\n        You should see something like this:\n        ```\n        Id                                          AppRoleId                            PrincipalDisplayName ResourceDisplayName\n        --                                          ---------                            -------------------- -------------------\n        BZyVP_2wPUy#############-################## 00000000-0000-0000-0000-000000000000 Allowed User         GraphLink Service\n        ```\n\n### 🛠 Complete Configuration Guide\n\n1. Create your own appsettings.json using the provided template:\n\n    Copy the template (Linux/macOS):\n    ```bash\n    cp appsettings.template.json appsettings.json\n    ```\n\n    Windows alternative:\n    ```cmd\n    copy appsettings.template.json appsettings.json\n    ```\n\n2. Edit the file with these exact values from you Azure AD app registration:\n    ```json\n    {\n        \"ApiKey\": \"supersecureapikey123!\", // Change the key\n        \"AzureAD\": {\n            \"ClientId\": \"########-####-####-####-############\", // From Azure AD \u003e App Registration \u003e Overview\n            \"TenantId\": \"########-####-####-####-############\", // From Azure AD \u003e Overview\n            \"ClientSecret\": \"########################################\", // From Azure AD \u003e Certificates \u0026 Secrets \u003e Secret value\n            \"RedirectUri\": \"http://localhost\",\n            \"AllowedAccounts\": [\n                {\n                    \"Email\": \"allowed.user@yourdomain.com\", // Exact user principal name\n                    \"Password\": \"allowed_user_password\", \n                    \"DisplayName\": \"Allowe User Service Account\",\n                    \"AllowedRecivers\": [ \n                        \"*@yourdomain.com\", // Allow sending to entire domain\n                        \"specific.partner@external.com\" // Specific allowed addresses\n                    ]\n                },\n                // Add more allowed accounts if needed\n            ]\n        }\n    }\n    ```\n    \n## 🧪 Development\n### Run Locally\n\n```bash\ndotnet build\ndotnet run\n```\n\n### Swagger UI\nOpen: [https://localhost:5001/swagger](https://localhost:5001/swagger)\nUse your API key to test endpoints.\n\n## 🤝 Contributing\nPRs and suggestions are welcome! Just fork, code, and submit a pull request 🚀\n\n## 🛡 License\nLicensed under [MIT](./LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinux-alex%2Fgraphlink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinux-alex%2Fgraphlink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinux-alex%2Fgraphlink/lists"}