Rewrite Init Commit
13
.eslintignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
30
.eslintrc.cjs
Normal file
@@ -0,0 +1,30 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:svelte/recommended',
|
||||
'prettier'
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020,
|
||||
extraFileExtensions: ['.svelte']
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2017: true,
|
||||
node: true
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.svelte'],
|
||||
parser: 'svelte-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
31
.gitignore
vendored
@@ -1,23 +1,10 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
13
.prettierignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
9
.prettierrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"useTabs": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"pluginSearchDirs": ["."],
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
}
|
||||
97
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"prettier.documentSelectors": ["**/*.svelte"],
|
||||
"tailwindCSS.classAttributes": [
|
||||
"class",
|
||||
"accent",
|
||||
"active",
|
||||
"background",
|
||||
"badge",
|
||||
"bgBackdrop",
|
||||
"bgDark",
|
||||
"bgDrawer",
|
||||
"bgLight",
|
||||
"blur",
|
||||
"border",
|
||||
"button",
|
||||
"buttonAction",
|
||||
"buttonBack",
|
||||
"buttonClasses",
|
||||
"buttonComplete",
|
||||
"buttonDismiss",
|
||||
"buttonNeutral",
|
||||
"buttonNext",
|
||||
"buttonPositive",
|
||||
"buttonTextCancel",
|
||||
"buttonTextConfirm",
|
||||
"buttonTextNext",
|
||||
"buttonTextPrevious",
|
||||
"buttonTextSubmit",
|
||||
"caretClosed",
|
||||
"caretOpen",
|
||||
"chips",
|
||||
"color",
|
||||
"cursor",
|
||||
"display",
|
||||
"element",
|
||||
"fill",
|
||||
"fillDark",
|
||||
"fillLight",
|
||||
"flex",
|
||||
"gap",
|
||||
"gridColumns",
|
||||
"height",
|
||||
"hover",
|
||||
"invalid",
|
||||
"justify",
|
||||
"meter",
|
||||
"padding",
|
||||
"position",
|
||||
"regionBackdrop",
|
||||
"regionBody",
|
||||
"regionCaption",
|
||||
"regionCaret",
|
||||
"regionCell",
|
||||
"regionCone",
|
||||
"regionContent",
|
||||
"regionControl",
|
||||
"regionDefault",
|
||||
"regionDrawer",
|
||||
"regionFoot",
|
||||
"regionFooter",
|
||||
"regionHead",
|
||||
"regionHeader",
|
||||
"regionIcon",
|
||||
"regionInterface",
|
||||
"regionInterfaceText",
|
||||
"regionLabel",
|
||||
"regionLead",
|
||||
"regionLegend",
|
||||
"regionList",
|
||||
"regionNavigation",
|
||||
"regionPage",
|
||||
"regionPanel",
|
||||
"regionRowHeadline",
|
||||
"regionRowMain",
|
||||
"regionTrail",
|
||||
"ring",
|
||||
"rounded",
|
||||
"select",
|
||||
"shadow",
|
||||
"slotDefault",
|
||||
"slotFooter",
|
||||
"slotHeader",
|
||||
"slotLead",
|
||||
"slotMessage",
|
||||
"slotMeta",
|
||||
"slotPageContent",
|
||||
"slotPageFooter",
|
||||
"slotPageHeader",
|
||||
"slotSidebarLeft",
|
||||
"slotSidebarRight",
|
||||
"slotTrail",
|
||||
"spacing",
|
||||
"text",
|
||||
"track",
|
||||
"width"
|
||||
]
|
||||
}
|
||||
21
LICENSE.md
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 luke-hagar-sp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
BIN
anchor.zip
|
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 426 B |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 747 B |
|
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
BIN
favicon.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
images/anchor_12.png
Normal file
|
After Width: | Height: | Size: 426 B |
BIN
images/anchor_128.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
images/anchor_32.png
Normal file
|
After Width: | Height: | Size: 747 B |
BIN
images/anchor_48.png
Normal file
|
After Width: | Height: | Size: 898 B |
32751
package-lock.json
generated
73
package.json
@@ -2,43 +2,44 @@
|
||||
"name": "anchor",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.9.3",
|
||||
"@emotion/styled": "^11.9.3",
|
||||
"@mui/material": "^5.8.7",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "INLINE_RUNTIME_CHUNK=false react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||
"format": "prettier --plugin-search-dir . --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^2.7.1"
|
||||
}
|
||||
"@floating-ui/dom": "^1.2.7",
|
||||
"@skeletonlabs/skeleton": "^1.5.1",
|
||||
"@sveltejs/adapter-auto": "^2.0.0",
|
||||
"@sveltejs/adapter-static": "^2.0.2",
|
||||
"@sveltejs/kit": "^1.5.0",
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@types/chrome": "^0.0.235",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"axios": "^1.4.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte": "^2.26.0",
|
||||
"highlight.js": "^11.8.0",
|
||||
"postcss": "^8.4.23",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
"sailpoint-api-client": "^1.0.4",
|
||||
"svelte": "^3.54.0",
|
||||
"svelte-check": "^3.0.1",
|
||||
"sveltekit-adapter-chrome-extension": "^2.0.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^4.3.0"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
||||
2494
pnpm-lock.yaml
generated
Normal file
6
postcss.config.cjs
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.8 KiB |
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 67 KiB |
45
src/App.css
@@ -1,45 +0,0 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
display: block;
|
||||
width: 40%;
|
||||
pointer-events: none;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
min-width: 400px;
|
||||
}
|
||||
1067
src/App.js
@@ -1,8 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
27
src/app.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
// and what to do when importing types
|
||||
declare namespace App {
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface Error {}
|
||||
// interface Platform {}
|
||||
}
|
||||
|
||||
declare type IdnSession = {
|
||||
tenant?: string;
|
||||
authType?: string;
|
||||
baseUrl?: string;
|
||||
logoutUrl?: string;
|
||||
accessToken?: string;
|
||||
refreshIn?: number | string;
|
||||
pollUrl?: string;
|
||||
strongAuth?: boolean | string;
|
||||
strongAuthUrl?: string;
|
||||
csrfToken?: string;
|
||||
expiration?: date;
|
||||
org?: string;
|
||||
region?: string;
|
||||
pod?: string;
|
||||
layer?: string;
|
||||
};
|
||||
12
src/app.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover" data-theme="sailpoint">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
5
src/app.postcss
Normal file
@@ -0,0 +1,5 @@
|
||||
/*place global styles here */
|
||||
html,
|
||||
body {
|
||||
@apply h-[600px] w-[800px];
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
17
src/index.js
@@ -1,17 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
77
src/lib/authentication.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import axios from 'axios';
|
||||
import { idnSession } from './settings';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
export async function getActiveTabURL() {
|
||||
const tabs = await chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
});
|
||||
|
||||
if (tabs.length === 0) {
|
||||
console.debug('No Tabs returned, Returning');
|
||||
return null;
|
||||
}
|
||||
|
||||
const activeTab = tabs[0];
|
||||
|
||||
if (!activeTab || !activeTab.url) {
|
||||
console.debug('No ActiveTab, Returning');
|
||||
return null;
|
||||
}
|
||||
|
||||
return new URL(activeTab.url);
|
||||
}
|
||||
|
||||
export async function checkAuth() {
|
||||
console.debug('Getting Session - ' + new Date().toLocaleTimeString());
|
||||
|
||||
let session;
|
||||
let tabUrl;
|
||||
|
||||
try {
|
||||
tabUrl = await getActiveTabURL();
|
||||
if (!tabUrl) {
|
||||
throw new Error('No Active Tab');
|
||||
}
|
||||
session = await axios.get(tabUrl.origin + '/ui/session');
|
||||
console.debug('Current page is a valid IDN Tenant');
|
||||
} catch (error) {
|
||||
const tenant = get(idnSession).tenant;
|
||||
if (tenant) {
|
||||
tabUrl = new URL(tenant);
|
||||
session = await axios.get(tenant + '/ui/session');
|
||||
console.debug('Using cached session');
|
||||
} else {
|
||||
console.debug('No Session, and Current Tab is not an IDN Tenant');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.debug('Setting timeout for ' + session.data.refreshIn + ' milliseconds');
|
||||
setTimeout(() => checkAuth(), session.data.refreshIn);
|
||||
|
||||
const sessionData = {
|
||||
...session.data,
|
||||
expiration: new Date(Date.now() + session.data.refreshIn)
|
||||
};
|
||||
|
||||
try {
|
||||
const hostingData = await axios.get(`${session.data.baseUrl}/beta/tenant-data/hosting-data`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${session.data.accessToken}`
|
||||
}
|
||||
});
|
||||
|
||||
sessionData.tenant = tabUrl.origin;
|
||||
sessionData.org = hostingData.data.org;
|
||||
sessionData.pod = hostingData.data.pod;
|
||||
sessionData.layer = hostingData.data.layer;
|
||||
sessionData.region = hostingData.data.region;
|
||||
|
||||
idnSession.set(sessionData);
|
||||
} catch (error) {
|
||||
console.error('Error fetching hosting data:', error);
|
||||
}
|
||||
}
|
||||
6
src/lib/settings.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { localStorageStore } from '@skeletonlabs/skeleton';
|
||||
import type { Writable } from 'svelte/store';
|
||||
|
||||
export const idnSession: Writable<IdnSession> = localStorageStore('tenantData', {
|
||||
tenant: 'https://whatever.com'
|
||||
});
|
||||
117
src/lib/theme-sailpoint.css
Normal file
@@ -0,0 +1,117 @@
|
||||
:root {
|
||||
/* =~= Theme Properties =~= */
|
||||
--theme-font-family-base: system-ui;
|
||||
--theme-font-family-heading: system-ui;
|
||||
--theme-font-color-base: 0 0 0;
|
||||
--theme-font-color-dark: 255 255 255;
|
||||
--theme-rounded-base: 9999px;
|
||||
--theme-rounded-container: 8px;
|
||||
--theme-border-base: 1px;
|
||||
/* =~= Theme On-X Colors =~= */
|
||||
--on-primary: 255 255 255;
|
||||
--on-secondary: 255 255 255;
|
||||
--on-tertiary: 255 255 255;
|
||||
--on-success: 255 255 255;
|
||||
--on-warning: 255 255 255;
|
||||
--on-error: 255 255 255;
|
||||
--on-surface: 255 255 255;
|
||||
/* =~= Theme Colors =~= */
|
||||
/* primary | #0033a1 */
|
||||
--color-primary-50: 217 224 241; /* ⬅ #d9e0f1 */
|
||||
--color-primary-100: 204 214 236; /* ⬅ #ccd6ec */
|
||||
--color-primary-200: 191 204 232; /* ⬅ #bfcce8 */
|
||||
--color-primary-300: 153 173 217; /* ⬅ #99add9 */
|
||||
--color-primary-400: 77 112 189; /* ⬅ #4d70bd */
|
||||
--color-primary-500: 0 51 161; /* ⬅ #0033a1 */
|
||||
--color-primary-600: 0 46 145; /* ⬅ #002e91 */
|
||||
--color-primary-700: 0 38 121; /* ⬅ #002679 */
|
||||
--color-primary-800: 0 31 97; /* ⬅ #001f61 */
|
||||
--color-primary-900: 0 25 79; /* ⬅ #00194f */
|
||||
/* secondary | #0071ce */
|
||||
--color-secondary-50: 217 234 248; /* ⬅ #d9eaf8 */
|
||||
--color-secondary-100: 204 227 245; /* ⬅ #cce3f5 */
|
||||
--color-secondary-200: 191 220 243; /* ⬅ #bfdcf3 */
|
||||
--color-secondary-300: 153 198 235; /* ⬅ #99c6eb */
|
||||
--color-secondary-400: 77 156 221; /* ⬅ #4d9cdd */
|
||||
--color-secondary-500: 0 113 206; /* ⬅ #0071ce */
|
||||
--color-secondary-600: 0 102 185; /* ⬅ #0066b9 */
|
||||
--color-secondary-700: 0 85 155; /* ⬅ #00559b */
|
||||
--color-secondary-800: 0 68 124; /* ⬅ #00447c */
|
||||
--color-secondary-900: 0 55 101; /* ⬅ #003765 */
|
||||
/* tertiary | #54c0e8 */
|
||||
--color-tertiary-50: 229 246 252; /* ⬅ #e5f6fc */
|
||||
--color-tertiary-100: 221 242 250; /* ⬅ #ddf2fa */
|
||||
--color-tertiary-200: 212 239 249; /* ⬅ #d4eff9 */
|
||||
--color-tertiary-300: 187 230 246; /* ⬅ #bbe6f6 */
|
||||
--color-tertiary-400: 135 211 239; /* ⬅ #87d3ef */
|
||||
--color-tertiary-500: 84 192 232; /* ⬅ #54c0e8 */
|
||||
--color-tertiary-600: 76 173 209; /* ⬅ #4cadd1 */
|
||||
--color-tertiary-700: 63 144 174; /* ⬅ #3f90ae */
|
||||
--color-tertiary-800: 50 115 139; /* ⬅ #32738b */
|
||||
--color-tertiary-900: 41 94 114; /* ⬅ #295e72 */
|
||||
/* success | #93d500 */
|
||||
--color-success-50: 239 249 217; /* ⬅ #eff9d9 */
|
||||
--color-success-100: 233 247 204; /* ⬅ #e9f7cc */
|
||||
--color-success-200: 228 245 191; /* ⬅ #e4f5bf */
|
||||
--color-success-300: 212 238 153; /* ⬅ #d4ee99 */
|
||||
--color-success-400: 179 226 77; /* ⬅ #b3e24d */
|
||||
--color-success-500: 147 213 0; /* ⬅ #93d500 */
|
||||
--color-success-600: 132 192 0; /* ⬅ #84c000 */
|
||||
--color-success-700: 110 160 0; /* ⬅ #6ea000 */
|
||||
--color-success-800: 88 128 0; /* ⬅ #588000 */
|
||||
--color-success-900: 72 104 0; /* ⬅ #486800 */
|
||||
/* warning | #EAB308 */
|
||||
--color-warning-50: 252 244 218; /* ⬅ #fcf4da */
|
||||
--color-warning-100: 251 240 206; /* ⬅ #fbf0ce */
|
||||
--color-warning-200: 250 236 193; /* ⬅ #faecc1 */
|
||||
--color-warning-300: 247 225 156; /* ⬅ #f7e19c */
|
||||
--color-warning-400: 240 202 82; /* ⬅ #f0ca52 */
|
||||
--color-warning-500: 234 179 8; /* ⬅ #EAB308 */
|
||||
--color-warning-600: 211 161 7; /* ⬅ #d3a107 */
|
||||
--color-warning-700: 176 134 6; /* ⬅ #b08606 */
|
||||
--color-warning-800: 140 107 5; /* ⬅ #8c6b05 */
|
||||
--color-warning-900: 115 88 4; /* ⬅ #735804 */
|
||||
/* error | #cc27b0 */
|
||||
--color-error-50: 247 223 243; /* ⬅ #f7dff3 */
|
||||
--color-error-100: 245 212 239; /* ⬅ #f5d4ef */
|
||||
--color-error-200: 242 201 235; /* ⬅ #f2c9eb */
|
||||
--color-error-300: 235 169 223; /* ⬅ #eba9df */
|
||||
--color-error-400: 219 104 200; /* ⬅ #db68c8 */
|
||||
--color-error-500: 204 39 176; /* ⬅ #cc27b0 */
|
||||
--color-error-600: 184 35 158; /* ⬅ #b8239e */
|
||||
--color-error-700: 153 29 132; /* ⬅ #991d84 */
|
||||
--color-error-800: 122 23 106; /* ⬅ #7a176a */
|
||||
--color-error-900: 100 19 86; /* ⬅ #641356 */
|
||||
/* surface | #415364 */
|
||||
--color-surface-50: 227 229 232; /* ⬅ #e3e5e8 */
|
||||
--color-surface-100: 217 221 224; /* ⬅ #d9dde0 */
|
||||
--color-surface-200: 208 212 216; /* ⬅ #d0d4d8 */
|
||||
--color-surface-300: 179 186 193; /* ⬅ #b3bac1 */
|
||||
--color-surface-400: 122 135 147; /* ⬅ #7a8793 */
|
||||
--color-surface-500: 65 83 100; /* ⬅ #415364 */
|
||||
--color-surface-600: 59 75 90; /* ⬅ #3b4b5a */
|
||||
--color-surface-700: 49 62 75; /* ⬅ #313e4b */
|
||||
--color-surface-800: 39 50 60; /* ⬅ #27323c */
|
||||
--color-surface-900: 32 41 49; /* ⬅ #202931 */
|
||||
}
|
||||
|
||||
/* Applied to body with `<body data-theme="sailpoint">` */
|
||||
/* Created with: https://csshero.org/mesher/ */
|
||||
[data-theme='sailpoint'] {
|
||||
/* prettier-ignore */
|
||||
background-color:hsla(197,0%,100%,1);
|
||||
background-image: radial-gradient(at 44% 23%, hsla(220, 100%, 31%, 0.36) 0px, transparent 50%),
|
||||
radial-gradient(at 93% 7%, hsla(207, 100%, 40%, 0.58) 0px, transparent 50%),
|
||||
radial-gradient(at 86% 77%, hsla(195, 76%, 61%, 0.55) 0px, transparent 50%),
|
||||
radial-gradient(at 45% 84%, hsla(310, 67%, 47%, 0.48) 0px, transparent 50%);
|
||||
background-repeat: no-repeat, no-repeat, no-repeat;
|
||||
}
|
||||
.dark [data-theme='sailpoint'] {
|
||||
/* prettier-ignore */
|
||||
/* background-color:hsla(205,19%,68%,0.54); */
|
||||
background-image: radial-gradient(at 44% 23%, hsla(220, 100%, 31%, 0.36) 0px, transparent 50%),
|
||||
radial-gradient(at 93% 7%, hsla(207, 100%, 40%, 0.58) 0px, transparent 50%),
|
||||
radial-gradient(at 86% 77%, hsla(195, 76%, 61%, 0.55) 0px, transparent 50%),
|
||||
radial-gradient(at 45% 84%, hsla(310, 67%, 47%, 0.48) 0px, transparent 50%);
|
||||
background-repeat: no-repeat, no-repeat, no-repeat;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,13 +0,0 @@
|
||||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
75
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,75 @@
|
||||
<script lang="ts">
|
||||
// The ordering of these imports is critical to your app working properly
|
||||
import '$lib/theme-sailpoint.css';
|
||||
// If you have source.organizeImports set to true in VSCode, then it will auto change this ordering
|
||||
import '@skeletonlabs/skeleton/styles/skeleton.css';
|
||||
// Most of your app wide CSS should be put in this file
|
||||
import '../app.postcss';
|
||||
|
||||
import { AppBar, AppShell, storeHighlightJs } from '@skeletonlabs/skeleton';
|
||||
|
||||
import { checkAuth } from '$lib/authentication';
|
||||
import { idnSession } from '$lib/settings';
|
||||
import dayjs from 'dayjs';
|
||||
import hljs from 'highlight.js';
|
||||
import 'highlight.js/styles/github-dark.css';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
storeHighlightJs.set(hljs);
|
||||
|
||||
onMount(async () => checkAuth());
|
||||
|
||||
let now = dayjs();
|
||||
let minutesUntil = dayjs($idnSession?.expiration).diff(now, 'minutes');
|
||||
let secondsUntil = dayjs($idnSession?.expiration).diff(now, 'seconds') - minutesUntil * 60;
|
||||
|
||||
setInterval(function () {
|
||||
now = dayjs();
|
||||
minutesUntil = dayjs($idnSession?.expiration).diff(now, 'minutes');
|
||||
secondsUntil = dayjs($idnSession?.expiration).diff(now, 'seconds') - minutesUntil * 60;
|
||||
}, 1000);
|
||||
</script>
|
||||
|
||||
<AppShell>
|
||||
<svelte:fragment slot="header">
|
||||
<AppBar>
|
||||
<svelte:fragment slot="lead">
|
||||
<div class="flex flex-row gap-4">
|
||||
<a class="btn btn-sm variant-filled" href="/">Tenant</a>
|
||||
<a class="btn btn-sm variant-filled" href="/session">Session</a>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="trail">
|
||||
<div class="p-1 top-0 right-0 flex flex-row gap-2">
|
||||
{#if minutesUntil < 0 || secondsUntil < 0}
|
||||
<p class="text-xs text-white my-auto">
|
||||
Strong Auth: <span class="text-red-500">Expired</span>
|
||||
</p>
|
||||
<p class="text-xs text-white my-auto">
|
||||
Session Timer: <span class="text-red-500">Expired</span>
|
||||
</p>
|
||||
{:else}
|
||||
<p class="text-xs text-white my-auto">
|
||||
Strong Auth: {#if $idnSession.strongAuth === true}
|
||||
<span class="text-green-500">True</span>
|
||||
{:else}
|
||||
<span class="text-red-500">True</span>
|
||||
{/if}
|
||||
</p>
|
||||
<p class="text-xs text-white my-auto">
|
||||
Session Timer: {minutesUntil}:{#if secondsUntil < 10}
|
||||
{`0${secondsUntil}`}
|
||||
{:else}
|
||||
{secondsUntil}
|
||||
{/if}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</AppBar>
|
||||
</svelte:fragment>
|
||||
|
||||
<!-- Router Slot -->
|
||||
<slot />
|
||||
<!-- ---- / ---- -->
|
||||
</AppShell>
|
||||
1
src/routes/+layout.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const prerender = true;
|
||||
22
src/routes/+page.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { idnSession } from '$lib/settings';
|
||||
</script>
|
||||
|
||||
<div class="p-2 flex flex-row gap-2">
|
||||
<div class="p-1">
|
||||
<p class="underline text-lg">Tenant Info</p>
|
||||
<p class="text-sm">Tenant: {$idnSession.org}</p>
|
||||
<p class="text-sm">Region: {$idnSession.region}</p>
|
||||
<p class="text-sm">Pod: {$idnSession.pod}</p>
|
||||
</div>
|
||||
<div class="p-1">
|
||||
<p class="underline text-lg">Quick Links</p>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={$idnSession.tenant + '/ui/admin#admin:dashboard:overview'}
|
||||
>
|
||||
Tenant Dashboard
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
8
src/routes/session/+page.svelte
Normal file
@@ -0,0 +1,8 @@
|
||||
<script>
|
||||
import { idnSession } from '$lib/settings';
|
||||
import { CodeBlock } from '@skeletonlabs/skeleton';
|
||||
</script>
|
||||
|
||||
<div class="p-1">
|
||||
<CodeBlock lineNumbers language="json" code={JSON.stringify($idnSession, null, ' ')} />
|
||||
</div>
|
||||
@@ -1,5 +0,0 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
BIN
static/favicon.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
static/images/anchor_12.png
Normal file
|
After Width: | Height: | Size: 426 B |
BIN
static/images/anchor_128.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
static/images/anchor_32.png
Normal file
|
After Width: | Height: | Size: 747 B |
BIN
static/images/anchor_48.png
Normal file
|
After Width: | Height: | Size: 898 B |
19
static/manifest.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Anchor",
|
||||
"description": "Chrome extension built to aid in working with IdentityNow",
|
||||
"version": "0.0.2",
|
||||
"manifest_version": 3,
|
||||
"icons": {
|
||||
"12": "images/anchor_12.png",
|
||||
"32": "images/anchor_32.png",
|
||||
"48": "images/anchor_48.png",
|
||||
"128": "images/anchor_128.png"
|
||||
},
|
||||
"permissions": ["tabs"],
|
||||
"host_permissions": ["http://*/", "https://*/"],
|
||||
"action": {
|
||||
"default_popup": "index.html",
|
||||
"default_icon": "images/anchor_32.png",
|
||||
"default_title": "Anchor"
|
||||
}
|
||||
}
|
||||
26
svelte.config.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import adapter from 'sveltekit-adapter-chrome-extension';
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter({
|
||||
// default options are shown
|
||||
pages: 'build',
|
||||
assets: 'build',
|
||||
fallback: null,
|
||||
precompress: false,
|
||||
manifest: 'manifest.json'
|
||||
}),
|
||||
appDir: 'app'
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
17
tailwind.config.cjs
Normal file
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
'./src/**/*.{html,js,svelte,ts}',
|
||||
require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
|
||||
],
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
require('@tailwindcss/typography'),
|
||||
...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
|
||||
]
|
||||
};
|
||||
17
tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
6
vite.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()]
|
||||
});
|
||||