<!doctype html>
<html data-bs-theme="dark">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Bootstrap -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
    <!-- UIcons by Flaticon (https://www.flaticon.com/uicons) -->
    <link rel='stylesheet' href='https://cdn-uicons.flaticon.com/2.4.0/uicons-regular-rounded/css/uicons-regular-rounded.css'>
    <link rel='stylesheet' href='https://cdn-uicons.flaticon.com/2.4.0/uicons-solid-rounded/css/uicons-solid-rounded.css'>
    <link rel='stylesheet' href='https://cdn-uicons.flaticon.com/2.4.0/uicons-bold-rounded/css/uicons-bold-rounded.css'>
    <!-- DataTables & jQuery -->
    <link href="https://cdn.datatables.net/2.1.8/css/dataTables.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/buttons/3.2.0/css/buttons.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/colreorder/2.0.4/css/colReorder.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/fixedcolumns/5.0.4/css/fixedColumns.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/responsive/3.0.3/css/responsive.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/scroller/2.4.3/css/scroller.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/select/2.1.0/css/select.bootstrap5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
    <script src="https://cdn.datatables.net/2.1.8/js/dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/2.1.8/js/dataTables.bootstrap5.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/3.2.0/js/dataTables.buttons.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/3.2.0/js/buttons.bootstrap5.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/3.2.0/js/buttons.colVis.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/3.2.0/js/buttons.html5.min.js"></script>
    <script src="https://cdn.datatables.net/colreorder/2.0.4/js/dataTables.colReorder.min.js"></script>
    <script src="https://cdn.datatables.net/fixedcolumns/5.0.4/js/dataTables.fixedColumns.min.js"></script>
    <script src="https://cdn.datatables.net/responsive/3.0.3/js/dataTables.responsive.min.js"></script>
    <script src="https://cdn.datatables.net/responsive/3.0.3/js/responsive.bootstrap5.js"></script>
    <script src="https://cdn.datatables.net/scroller/2.4.3/js/dataTables.scroller.min.js"></script>
    <script src="https://cdn.datatables.net/select/2.1.0/js/dataTables.select.min.js"></script>
    <!-- Prism Syntax Highlight -->
    <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-okaidia.min.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-json.min.js"></script>
    <!-- DOMPurify -->
    <script type="text/javascript" language="javascript" src="{{url_for('static', filename='js/purify.min.js')}}"></script>
    <!-- Static JS & CSS -->
    <script type="text/javascript" language="javascript" src="{{url_for('static', filename='js/theme.js')}}"></script>
    <script type="text/javascript" language="javascript" src="{{url_for('static', filename='js/functions.js')}}"></script>
    <link rel="stylesheet" type="text/css" href="{{url_for('static', filename='css/style.css')}}">

    <title>{{title}}</title>
</head>
<body>
    <!-- Navbar -->
    <nav class="navbar sticky-top navbar-expand-xl bg-body-tertiary">
        <div class="container-fluid">
            <a class="navbar-brand" href="/">GraphSpy</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNavDropdown">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="/">Settings</a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Tokens
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('refresh_tokens')}}">Refresh Tokens</a></li>
                            <li><a class="dropdown-item" href="{{url_for('access_tokens')}}">Access Tokens</a></li>
                        </ul>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Authentication
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('device_codes')}}">Device Codes</a></li>
                            <li><a class="dropdown-item" href="{{url_for('mfa')}}">MFA Methods</a></li>
                        </ul>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Custom
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('custom_requests')}}">Custom Requests</a></li>
                            <li><a class="dropdown-item" href="{{url_for('generic_search')}}">Generic MSGraph Search</a></li>
                        </ul>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Files
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('recent_files')}}">Recent Files</a></li>
                            <li><a class="dropdown-item" href="{{url_for('shared_with_me')}}">Files Shared With Me</a></li>
                            <li><a class="dropdown-item" href="{{url_for('onedrive')}}">OneDrive</a></li>
                        </ul>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            SharePoint
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('sharepoint_sites')}}">SharePoint Sites</a></li>
                            <li><a class="dropdown-item" href="{{url_for('sharepoint_drives')}}">SharePoint Drives</a></li>
                            <li><a class="dropdown-item" href="{{url_for('sharepoint')}}">SharePoint Files</a></li>
                        </ul>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Outlook
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('outlook')}}">Outlook Web</a></li>
                            <li><a class="dropdown-item" href="{{url_for('outlook_graph')}}">Outlook Graph</a></li>
                        </ul>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{{url_for('teams')}}">Teams</a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Entra ID
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="{{url_for('entra_users')}}">Users</a></li>
                        </ul>
                    </li>
                    <li class="nav-item">
                        <span class="d-inline-block" id="nav-azure-disabled" data-bs-toggle="popover" data-bs-trigger="hover focus" data-bs-content="Coming soon!" data-bs-placement="bottom">
                            <a class="nav-link disabled">Azure</a>
                        </span>
                    </li>
                </ul>
            </div>
            <div class="d-flex align-items-center order-lg-last">
                <ul class="navbar-nav flex-row">
                    <li class="nav-item">
                        <a class="nav-link p-1 px-3" href="https://github.com/sponsors/RedByte1337" target="_blank" id="support-graphspy-icon" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Support GraphSpy" onmouseover="this.style.color='#ff6b81'" onmouseout="this.style.color=''">
                            <i class="fi fi-rr-heart" style="vertical-align: -0.30em; font-size: 1.25em;" ></i>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" data-bs-toggle="offcanvas" href="#offcanvas-side-menu" role="button">Token Options</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <script>
        const azurePopover = new bootstrap.Popover(document.getElementById('nav-azure-disabled'))
        const supportGraphSpyTooltip = new bootstrap.Tooltip(document.getElementById('support-graphspy-icon'))
    </script>
    <!-- Placeholders -->
    <div id="alert_placeholder"></div>
    <div id="toast_placeholder" class="toast-container position-fixed end-0 p-3"></div>
    <!-- Side Menu -->
    <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvas-side-menu" aria-labelledby="offcanvasLabel">
        <div class="offcanvas-header">
            <h2 class="offcanvas-title" id="offcanvasLabel">Token Options</h2>
            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body">
            <div>
                <form id="side_menu_refresh_to_access_token_form" class="row g-3">
                    <div class="col-12">
                        <label for="resource_input_side" class="form-label">Resource</label>
                        <input list="resource_list_side" id="resource_input_side" class="form-control" placeholder="https://graph.microsoft.com">
                        <datalist id="resource_list_side">
                            <option value="defined_in_token">Defined in Refresh Token</option>
                            <option value="https://graph.microsoft.com">MSGraph</option>
                            <option value="https://graph.windows.net/">AAD Graph</option>
                            <option value="https://outlook.office365.com">Outlook</option>
                            <option value="https://api.spaces.skype.com/">MSTeams</option>
                            <option value="https://management.core.windows.net/">AzureCoreManagement</option>
                            <option value="https://management.azure.com">AzureManagement</option>
                        </datalist>
                    </div>
                    <div class="col-12">
                        <label for="client_id_input_side" class="form-label">Client ID</label>
                        <input list="client_id_list_side" id="client_id_input_side" class="form-control" placeholder="d3590ed6-52b3-4102-aeff-aad2292ab01c">
                        <datalist id="client_id_list_side">
                            <option value="d3590ed6-52b3-4102-aeff-aad2292ab01c">Microsoft Office</option>
                            <option value="1fec8e78-bce4-4aaf-ab1b-5451cc387264">Microsoft Teams</option>
                            <option value="27922004-5251-4030-b22d-91ecd9a37ea4">Outlook Mobile</option>
                            <option value="b26aadf8-566f-4478-926f-589f601d9c74">OneDrive</option>
                            <option value="d326c1ce-6cc6-4de2-bebc-4591e5e13ef0">SharePoint</option>
                            <option value="00b41c95-dab0-4487-9791-b9d2c32c80f2">Office 365 Management</option>
                            <option value="04b07795-8ddb-461a-bbee-02f9e1bf7b46">Microsoft Azure CLI</option>
                            <option value="1950a258-227b-4e31-a9cf-717495945fc2">Microsoft Azure PowerShell</option>
                        </datalist>
                    </div>
                    <div class="col-12">
                        <button type="Button" class="btn btn-primary" onclick="refreshToAccessToken(refresh_token_id_side.value, client_id_input_side.value, resource_input_side.value, '', false, true);reloadTables()">Refresh and activate</button>
                    </div>
                </form>
                <br>
            </div>
            <div>
                <h4>Access Token</h4>
                <form id="side_menu_access_token_form" class="row row-cols-auto">
                    <div class="input-group">
                        <input type="text" id="access_token_id_side" class="form-control" size="1" readonly>
                        <button type="Button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#access_token_modal" onclick="$('#access_token_modal_table').DataTable().ajax.reload(null, false)">Select...</button>
                    </div>
                </form>
                <div class="card text-bg-secondary mb-3 mt-3" id="access_token_card">
                    <div class="card-body">
                        <dl>
                            <dt>User</dt>
                            <dd id="access_token_info_user"></dd>
                            <dt>Resource</dt>
                            <dd id="access_token_info_resource"></dd>
                            <dt>Client ID</dt>
                            <dd id="access_token_info_clientid"></dd>
                            <dt>Scope</dt>
                            <dd id="access_token_info_scope"></dd>
                            <dt>Expires At</dt>
                            <dd id="access_token_info_expires"></dd>
                        </dl>
                    </div>
                </div>
            </div>
            <div>
                <h4>Refresh Token</h4>
                <form id="side_menu_refresh_token_form" class="row row-cols-auto">
                    <div class="input-group">
                        <input type="text" id="refresh_token_id_side" class="form-control" size="1" required>
                        <button class="btn btn-outline-primary" type="button" data-bs-toggle="modal" data-bs-target="#refresh_token_modal" onclick="$('#refresh_token_modal_table').DataTable().ajax.reload(null, false)">Select...</button>
                    </div>
                </form>
                <div class="card text-bg-secondary mb-3 mt-3" id="refresh_token_card">
                    <div class="card-body">
                        <dl>
                            <dt>User</dt>
                            <dd id="refresh_token_info_user"></dd>
                            <dt>Resource</dt>
                            <dd id="refresh_token_info_resource"></dd>
                            <dt>Tenant ID</dt>
                            <dd id="refresh_token_info_tenant_id"></dd>
                            <dt>Foci</dt>
                            <dd id="refresh_token_info_foci"></dd>
                            <dt>Description</dt>
                            <dd id="refresh_token_info_description"></dd>
                        </dl>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script>
        // Obtain access token info
        function obtainAccessTokenInfo() {
            getActiveAccessToken(document.getElementById("side_menu_access_token_form").access_token_id_side);
            if (document.getElementById("side_menu_access_token_form").access_token_id_side.value == 0) {
                $('#access_token_info_user').text("");
                $('#access_token_info_resource').text("");
                $('#resource_input_side').val("");
                $('#access_token_info_clientid').text("");
                $('#client_id_input_side').val("");
                $('#access_token_info_scope').text("");
                $('#access_token_info_expires').text("");
                $("#access_token_card").removeClass(function (index, className) {
                    return (className.match(/(^|\s)text-bg-\S+/g) || []).join(' ');
                });
                $("#access_token_card").addClass("text-bg-secondary")
                return
            }
            let response_a = $.ajax({
                type: "GET",
                async: false,
                url: "/api/decode_token/" + document.getElementById("side_menu_access_token_form").access_token_id_side.value
            });
            if (response_a.responseText.startsWith("[Error]")) {
                bootstrapToast("Access Token Error", response_a.responseText);
                return
            }
            access_token_info = JSON.parse(response_a.responseText);
            $('#access_token_info_user').text(access_token_info.unique_name);
            $('#access_token_info_resource').text(access_token_info.aud);
            $('#resource_input_side').val(access_token_info.aud);
            $('#access_token_info_clientid').text(access_token_info.appid);
            $('#client_id_input_side').val(access_token_info.appid);
            $('#access_token_info_scope').text(access_token_info.scp);
            var expiry_date = new Date(access_token_info.exp * 1000);
            $('#access_token_info_expires').text(`${expiry_date.toLocaleDateString()} ${expiry_date.toTimeString().split(" ")[0]}`);
            $("#access_token_card").removeClass(function (index, className) {
                return (className.match(/(^|\s)text-bg-\S+/g) || []).join(' ');
            });
            if (expiry_date > new Date()) {
                $("#access_token_card").addClass("text-bg-success")
            } else {
                $("#access_token_card").addClass("text-bg-danger")
            }

        }
        // Obtain refresh token info
        function obtainRefreshTokenInfo() {
            getActiveRefreshToken(document.getElementById("side_menu_refresh_token_form").refresh_token_id_side);
            if (document.getElementById("side_menu_refresh_token_form").refresh_token_id_side.value == 0) {
                $('#refresh_token_info_user').text("");
                $('#refresh_token_info_resource').text("");
                $('#refresh_token_info_description').text("");
                $('#refresh_token_info_tenant_id').text("");
                $('#refresh_token_info_foci').text("");
                return
            }
            let response_r = $.ajax({
                type: "GET",
                async: false,
                url: "/api/get_refresh_token/" + document.getElementById("side_menu_refresh_token_form").refresh_token_id_side.value
            });
            refresh_token_info = JSON.parse(response_r.responseText);
            $('#refresh_token_info_user').text(refresh_token_info.user);
            $('#refresh_token_info_resource').text(refresh_token_info.resource);
            $('#refresh_token_info_description').text(refresh_token_info.description);
            $('#refresh_token_info_tenant_id').text(refresh_token_info.tenant_id);
            $('#refresh_token_info_foci').text(refresh_token_info.foci);
        }
        obtainAccessTokenInfo();
        obtainRefreshTokenInfo();
    </script>
    <!-- Modals -->
    <div id="modal_container">
        {% include 'access_token_modal.html' %}
        {% include 'refresh_token_modal.html' %}
    </div>
    <!-- Template Content -->
    <div class="container-fluid">
        {%block content%}
        {%endblock content%}
    </div>
    <!-- Enable/Disable Datatable Error Messages -->
    <script>
        var table_error_messages = "{{ config['table_error_messages'] }}";
        $.fn.dataTable.ext.errMode = 'none';
        if (table_error_messages == "enabled") {
            // Catch datatable error messages and convert them to toast messages
            $('table').on('error.dt', function (e, settings, techNote, message) {
                bootstrapToast("DataTables Error", message);
            });
        }
    </script>
</body>
</html>