Compare commits
No commits in common. "91956d1e897c73c0e770a6178aa3be6b733895cd" and "43abe6f002f10e9f1098628847a64c2a8849c637" have entirely different histories.
91956d1e89
...
43abe6f002
5
web/babel.config.js
Normal file
5
web/babel.config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/app'
|
||||||
|
]
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Building site..."
|
|
||||||
yarn build
|
|
||||||
echo "Uploading site..."
|
|
||||||
duck -y --username sso-tools --upload ftps://uk.storage.bunnycdn.com/ dist/*
|
|
||||||
echo "Clearing CDN cache..."
|
|
||||||
curl -X POST -H "AccessKey: $BUNNY_PERSONAL" https://api.bunny.net/pullzone/782714/purgeCache
|
|
||||||
echo "Done."
|
|
@ -3,21 +3,47 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite --port 3300",
|
"serve": "vue-cli-service serve",
|
||||||
"build": "vite build"
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint",
|
||||||
|
"predeploy": "yarn build",
|
||||||
|
"deploy": "aws s3 sync dist/ s3://sso.tools"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "^7.0.96",
|
"core-js": "^2.6.5",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.3",
|
||||||
"vue": "^3.2.45",
|
"vue": "^2.6.10",
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^3.0.6",
|
||||||
"vuetify": "^3.0.1",
|
"vuetify": "^1.5.13",
|
||||||
"vuex": "^4.1.0"
|
"vuex": "^3.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^3.2.0",
|
"@vue/cli-plugin-babel": "^3.7.0",
|
||||||
"vite": "^3.2.4",
|
"@vue/cli-plugin-eslint": "^3.7.0",
|
||||||
"vue-template-compiler": "^2.7.14"
|
"@vue/cli-service": "^3.7.0",
|
||||||
|
"babel-eslint": "^10.0.1",
|
||||||
|
"eslint": "^5.16.0",
|
||||||
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
|
"vue-template-compiler": "^2.5.21"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"rules": {},
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postcss": {
|
||||||
|
"plugins": {
|
||||||
|
"autoprefixer": {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="shortcut icon" href="/icon.png">
|
<link rel="icon" href="<%= BASE_URL %>icon.png">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
|
||||||
<title>SSO Tools</title>
|
<title>SSO Tools</title>
|
||||||
</head>
|
</head>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<strong>We're sorry but SSO Tools doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
<strong>We're sorry but SSO Tools doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
</noscript>
|
</noscript>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.js"></script>
|
<!-- built files will be auto injected -->
|
||||||
<script async defer data-website-id="d91e0265-3ca4-4ecb-a1d9-fc4e4f97d3bb" src="https://u.wilw.dev/umami.js"></script>
|
<script async defer data-website-id="d91e0265-3ca4-4ecb-a1d9-fc4e4f97d3bb" src="https://u.wilw.dev/umami.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
191
web/src/App.vue
191
web/src/App.vue
@ -1,59 +1,68 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<v-app class="d-flex flex-row">
|
<v-app>
|
||||||
|
|
||||||
<div class="d-flex justify-space-between align-center pl-4 pr-4 pt-2 pb-2 bg-indigo-lighten-5">
|
<v-toolbar >
|
||||||
<div>
|
<router-link :to="loggedIn ? '/dashboard' : '/'">
|
||||||
<router-link :to="loggedIn ? '/dashboard' : '/'">
|
<img :src="logo" style="height:50px;"/>
|
||||||
<img :src="logo" style="height:50px;"/>
|
</router-link>
|
||||||
</router-link>
|
<v-spacer></v-spacer>
|
||||||
</div>
|
<v-toolbar-items class="hidden-sm-and-down">
|
||||||
<div class="d-none d-sm-flex align-center">
|
<v-btn icon to="/dashboard"><v-icon>explore</v-icon></v-btn>
|
||||||
<div>
|
|
||||||
<v-btn flat to="/dashboard" class="mr-4" color="primary" variant='outline'>Dashboard</v-btn>
|
|
||||||
<v-btn color='indigo-lighten-2' flat icon v-if="loggedIn">
|
|
||||||
<v-icon icon="mdi-account" />
|
|
||||||
<v-menu activator="parent">
|
|
||||||
<v-list>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title>{{user.firstName}} {{user.lastName}}</v-list-item-title>
|
|
||||||
<v-list-item-sub-title class="text-grey">{{user.email}}</v-list-item-sub-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
|
|
||||||
<v-divider></v-divider>
|
<v-menu offset-y transition="slide-y-transition" v-if="user">
|
||||||
|
<template v-slot:activator="{ on }">
|
||||||
|
<v-btn icon v-on="on"><v-icon>person</v-icon></v-btn>
|
||||||
|
</template>
|
||||||
|
<v-card>
|
||||||
|
<v-list>
|
||||||
|
<v-list-tile avatar>
|
||||||
|
<v-list-tile-avatar color="teal">
|
||||||
|
<span class="white--text headline">{{user.firstName[0].toUpperCase()}}</span>
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
|
||||||
<v-list>
|
<v-list-tile-content>
|
||||||
<v-list-item to='/account'>
|
<v-list-tile-title>{{user.firstName}} {{user.lastName}}</v-list-tile-title>
|
||||||
<v-list-item-icon><v-icon icon="mdi-cogs" class="mr-2"/></v-list-item-icon>
|
<v-list-tile-sub-title>{{user.email}}</v-list-tile-sub-title>
|
||||||
<v-list-item-content>Account</v-list-item-content>
|
</v-list-tile-content>
|
||||||
</v-list-item>
|
</v-list-tile>
|
||||||
<v-list-item @click="logout">
|
</v-list>
|
||||||
<v-list-item-icon><v-icon icon="mdi-power" class="mr-2"/></v-list-item-icon>
|
|
||||||
<v-list-item-content>Logout</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-btn class="mr-2" flat v-on:click="openLogin" v-if="!loggedIn">Login</v-btn>
|
<v-divider></v-divider>
|
||||||
<v-btn color="teal" dark v-on:click="openRegister" v-if="!loggedIn">Create a free account</v-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex-grow-1">
|
<v-list>
|
||||||
|
<v-list-tile to='/account'>
|
||||||
|
<v-list-tile-action><v-icon>settings</v-icon></v-list-tile-action>
|
||||||
|
<v-list-tile-title>Account</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile @click="logout">
|
||||||
|
<v-list-tile-action>
|
||||||
|
<v-icon>power_settings_new</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-title>Logout</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
</v-list>
|
||||||
|
</v-card>
|
||||||
|
</v-menu>
|
||||||
|
|
||||||
|
<v-btn flat v-on:click="openLogin" v-if="!loggedIn">Login</v-btn>
|
||||||
|
<v-btn color="teal" dark v-on:click="openRegister" v-if="!loggedIn">Create a free account</v-btn>
|
||||||
|
</v-toolbar-items>
|
||||||
|
</v-toolbar>
|
||||||
|
|
||||||
|
<div style="min-height:100vh;">
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-footer class="bg-indigo-lighten-1 mt-10 d-block d-sm-flex justify-space-between flex-grow-0">
|
<v-footer dark height="auto">
|
||||||
<img :src="logoLight" style="height:50px;"/>
|
<v-card class="flex" flat tile>
|
||||||
<div>
|
<v-card-title class="teal">
|
||||||
<v-btn flat dark to='/privacy' class="mr-2">Privacy Policy</v-btn>
|
<img :src="logoLight" style="height:50px;"/>
|
||||||
<v-btn flat dark to="/terms">Terms of Use</v-btn>
|
<v-spacer></v-spacer>
|
||||||
</div>
|
<v-btn flat dark to='/privacy'>Privacy Policy</v-btn>
|
||||||
|
<v-btn flat dark to="terms">Terms of Use</v-btn>
|
||||||
|
</v-card-title>
|
||||||
|
</v-card>
|
||||||
</v-footer>
|
</v-footer>
|
||||||
|
|
||||||
<v-dialog v-model="registerOpen" persistent max-width="600px">
|
<v-dialog v-model="registerOpen" persistent max-width="600px">
|
||||||
@ -62,38 +71,42 @@
|
|||||||
<span class="headline">Create a free account</span>
|
<span class="headline">Create a free account</span>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<h4>Welcome to SSO Tools!</h4>
|
<p>Welcome to SSO Tools!</p>
|
||||||
<p>Registering takes less than a minute and we'll automatically associate the IDPs and other settings you've already setup with your new account.</p>
|
<p>Registering takes less than a minute and we'll automatically associate the IDPs and other settings you've already setup with your new account.</p>
|
||||||
|
<v-container grid-list-md>
|
||||||
|
<v-layout wrap>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="First name" required autofocus v-model="newUser.firstName"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Last name" v-model="newUser.lastName" />
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field type="email" label="Email address" v-model="newUser.email" />
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field :type="showPassword ? 'text' : 'password'" label="Password" v-model="newUser.password" :append-icon="showPassword ? 'visibility' : 'visibility_off'" @click:append="toggleShowPassword"/>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
<div class="d-flex mt-5">
|
<v-card>
|
||||||
<v-text-field class="mr-2" label="First name" required autofocus v-model="newUser.firstName"/>
|
<v-card-text>
|
||||||
<v-text-field label="Last name" v-model="newUser.lastName" />
|
<p>We collect this information from you for the sole purpose of creating and maintaining your account, and it will not be used for marketing purposes without your consent. Our Privacy Policy describes how we process your data in more detail.</p>
|
||||||
</div>
|
<v-btn to="/privacy" @click="closeRegister">Privacy Policy</v-btn>
|
||||||
<div class="d-flex mt-5">
|
|
||||||
<v-text-field class="mr-2" type="email" label="Email address" v-model="newUser.email" />
|
|
||||||
<v-text-field :type="showPassword ? 'text' : 'password'" hint="At least 8 characters" label="Password" v-model="newUser.password" :append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'" @click:append-inner="toggleShowPassword"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-card>
|
|
||||||
<v-card-text>
|
|
||||||
<p>We collect this information from you for the sole purpose of creating and maintaining your account, and it will not be used for marketing purposes without your consent. Our Privacy Policy describes how we process your data in more detail.</p>
|
|
||||||
<div class="d-flex mt-5">
|
|
||||||
<v-btn class="mr-2" to="/privacy" @click="closeRegister">Privacy Policy</v-btn>
|
|
||||||
<v-btn to="terms" @click="closeRegister">Terms of Use</v-btn>
|
<v-btn to="terms" @click="closeRegister">Terms of Use</v-btn>
|
||||||
</div>
|
<v-checkbox v-model="newUser.termsAgreed" label="I have read and I agree to the SSO Tools Privacy Policy and Terms of Use" required></v-checkbox>
|
||||||
<p class="mt-5">Please indicate below that you have read and you agree to the Privacy Policy and Terms of Use (the "terms").</p>
|
</v-card-text>
|
||||||
<v-checkbox v-model="newUser.termsAgreed" label="I have read and agree to the terms" required></v-checkbox>
|
</v-card>
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
|
|
||||||
<v-alert class="mt-5" v-if="registerError" type="error">
|
<v-alert :value="registerError" type="error">
|
||||||
<h4>Unable to register this account</h4>
|
<h4>Unable to register this account</h4>
|
||||||
<p>{{registerError}}</p>
|
<p>{{registerError}}</p>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn @click="closeRegister">Cancel</v-btn>
|
<v-btn color="secondary" flat @click="closeRegister">Cancel</v-btn>
|
||||||
<v-btn color="primary" @click="register" :loading="registering">Register</v-btn>
|
<v-btn color="primary" @click="register" :loading="registering">Register</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
@ -106,40 +119,44 @@
|
|||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<p>Welcome back!</p>
|
<p>Welcome back!</p>
|
||||||
<div class="d-flex mt-5">
|
<v-container grid-list-md>
|
||||||
<v-text-field class="mr-2" type="email" label="Email address" v-model="loginData.email" />
|
<v-layout wrap>
|
||||||
<v-text-field type="password" label="Password" @keyup.enter="login" v-model="loginData.password" />
|
<v-flex xs12 sm6>
|
||||||
</div>
|
<v-text-field type="email" label="Email address" v-model="loginData.email" />
|
||||||
<div class="d-flex justify-end mb-5">
|
</v-flex>
|
||||||
<v-btn @click="forgotPassword" flat>Forgotten your password?</v-btn>
|
<v-flex xs12 sm6>
|
||||||
</div>
|
<v-text-field type="password" label="Password" @keyup.enter="login" v-model="loginData.password" />
|
||||||
|
</v-flex>
|
||||||
<v-alert v-if="loginError" type="error">
|
</v-layout>
|
||||||
<h4>Unable to login</h4>
|
|
||||||
<p>{{loginError}}</p>
|
|
||||||
</v-alert>
|
|
||||||
|
|
||||||
|
<v-btn @click="forgotPassword" flat style="float:right;">Forgotten your password?</v-btn>
|
||||||
|
<div style="clear:both;" />
|
||||||
|
<v-alert :value="loginError" type="error">
|
||||||
|
<h4>Unable to login</h4>
|
||||||
|
<p>{{loginError}}</p>
|
||||||
|
</v-alert>
|
||||||
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn @click="closeLogin">Cancel</v-btn>
|
<v-btn color="secondary" flat @click="closeLogin">Cancel</v-btn>
|
||||||
<v-btn color="primary" @click="login" :loading="loggingIn">Login</v-btn>
|
<v-btn color="primary" @click="login" :loading="loggingIn">Login</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
<v-dialog v-model="forgottenPasswordOpen" persistent max-width="500px">
|
<v-dialog v-model="forgottenPasswordOpen" persistent max-width="300px">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
<span class="headline">Forgotten your SSO Tools password?</span>
|
<span class="headline">Forgotten your SSO Tools password?</span>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<p>No problem. Enter the email address of your account below, and if it exists we'll send a password-reset link to you.</p>
|
<p>No problem. Enter the email address of your account below, and if it exists we'll send a password-reset link to you.</p>
|
||||||
<v-text-field class="mt-5" type="email" label="Email address" v-model="loginData.email" />
|
<v-text-field type="email" label="Email address" v-model="loginData.email" />
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn @click="forgottenPasswordOpen = false">Cancel</v-btn>
|
<v-btn color="secondary" flat @click="forgottenPasswordOpen = false">Cancel</v-btn>
|
||||||
<v-btn color="primary" @click="resetPassword" :loading="resettingPassword">Send me a reset link</v-btn>
|
<v-btn color="primary" @click="resetPassword" :loading="resettingPassword">Send me a reset link</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 87 KiB |
Binary file not shown.
Before Width: | Height: | Size: 56 KiB |
@ -1,22 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container>
|
<v-container>
|
||||||
<h1>Your account</h1>
|
<h1 style="margin-bottom: 20px;">Your account</h1>
|
||||||
|
|
||||||
<v-card class="mt-10">
|
<v-card style="margin-bottom: 20px;">
|
||||||
<v-card-title><span class="headline">About you</span></v-card-title>
|
<v-card-title><span class="headline">About you</span></v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div class="d-flex mt-5">
|
<v-container grid-list-md>
|
||||||
<v-text-field class="mr-2" label="First name" v-model="user.firstName" />
|
<v-layout wrap>
|
||||||
<v-text-field label="Last name" v-model="user.lastName" />
|
<v-flex xs12 sm6>
|
||||||
</div>
|
<v-text-field label="First name" v-model="user.firstName" />
|
||||||
<div class="d-flex mt-2">
|
</v-flex>
|
||||||
<v-text-field class="w-50" label="Email address" v-model="user.email"/>
|
<v-flex xs12 sm6>
|
||||||
</div>
|
<v-text-field label="Last name" v-model="user.lastName" />
|
||||||
<p>Please note that if you change your email address we will notify both your old and new addresses.</p>
|
</v-flex>
|
||||||
<v-alert v-if="error" type="error">
|
<v-flex xs12 sm6>
|
||||||
<h4>Unable to update your profile</h4>
|
<v-text-field label="Email address" v-model="user.email"/>
|
||||||
<p>{{error}}</p>
|
</v-flex>
|
||||||
</v-alert>
|
<p>Please note that if you change your email address we will notify both your old and new addresses.</p>
|
||||||
|
</v-layout>
|
||||||
|
<v-alert :value="error" type="error">
|
||||||
|
<h4>Unable to update your profile</h4>
|
||||||
|
<p>{{error}}</p>
|
||||||
|
</v-alert>
|
||||||
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
@ -24,22 +30,28 @@
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-card class="mt-10">
|
<v-card style="margin-bottom: 20px;">
|
||||||
<v-card-title><span class="headline">Password</span></v-card-title>
|
<v-card-title><span class="headline">Password</span></v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<p>Change the password associated with your SSO Tools account. This does not affect the accounts of any IDP users you may manage.</p>
|
<v-container grid-list-md>
|
||||||
<div class="d-flex mt-5">
|
<p>Change the password associated with your SSO Tools account. This does not affect the accounts of any IDP users you may manage.</p>
|
||||||
<v-text-field class="mr-2" type="password" label="Current password" v-model="currentPassword" />
|
<v-layout wrap>
|
||||||
<v-text-field :type="showPassword ? 'text' : 'password'" label="New password (8+ characters)" v-model="newPassword" :append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'" @click:append-inner="showPassword = !showPassword"/>
|
<v-flex xs12 sm6>
|
||||||
</div>
|
<v-text-field type="password" label="Current password" v-model="currentPassword" />
|
||||||
<v-alert v-if="passwordError" type="error">
|
</v-flex>
|
||||||
<h4>Unable to change your password</h4>
|
<v-flex xs12 sm6>
|
||||||
<p>{{passwordError}}</p>
|
<v-text-field :type="showPassword ? 'text' : 'password'" label="New password (8+ characters)" v-model="newPassword" :append-icon="showPassword ? 'visibility' : 'visibility_off'" @click:append="showPassword = !showPassword"/>
|
||||||
</v-alert>
|
</v-flex>
|
||||||
<v-alert v-if="passwordSuccess" type="success">
|
</v-layout>
|
||||||
<h4>Password updated successfully</h4>
|
<v-alert :value="passwordError" type="error">
|
||||||
<p>Use your new password next time you login.</p>
|
<h4>Unable to change your password</h4>
|
||||||
</v-alert>
|
<p>{{passwordError}}</p>
|
||||||
|
</v-alert>
|
||||||
|
<v-alert :value="passwordSuccess" type="success">
|
||||||
|
<h4>Password updated successfully</h4>
|
||||||
|
<p>Use your new password next time you login.</p>
|
||||||
|
</v-alert>
|
||||||
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
@ -47,16 +59,22 @@
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-card class="mt-10">
|
<v-card>
|
||||||
<v-card-title><span class="headline">Delete your account</span></v-card-title>
|
<v-card-title><span class="headline">Delete your account</span></v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<p>If you delete your SSO Tools account, we'll also delete your account content. This includes Identity Providers, Service Providers, and any IdP users you have created.</p>
|
<v-container grid-list-md>
|
||||||
<p>To continue, please enter your account password.</p>
|
<p>If you delete your SSO Tools account, we'll also delete your account content. This includes Identity Providers, Service Providers, and any IdP users you have created.</p>
|
||||||
<v-text-field class="mt-5" type="password" label="Current password" v-model="deletePassword" />
|
<p>To continue, please enter your account password.</p>
|
||||||
<v-alert v-if="deleteError" type="error">
|
<v-layout wrap>
|
||||||
<h4>Unable to delete your account</h4>
|
<v-flex xs12 sm6>
|
||||||
<p>{{deleteError}}</p>
|
<v-text-field type="password" label="Current password" v-model="deletePassword" />
|
||||||
</v-alert>
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
<v-alert :value="deleteError" type="error">
|
||||||
|
<h4>Unable to delete your account</h4>
|
||||||
|
<p>{{deleteError}}</p>
|
||||||
|
</v-alert>
|
||||||
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
@ -1,58 +1,63 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<v-container fluid="true">
|
<v-container grid-list-xl :fluid="true">
|
||||||
<h1>Welcome back<span v-if="user">, {{user.firstName}}</span></h1>
|
<h1>Welcome back<span v-if="user">, {{user.firstName}}</span></h1>
|
||||||
|
|
||||||
<div class="d-block d-sm-flex mt-10">
|
<v-layout style="margin-top:30px;">
|
||||||
<div class="mr-sm-2 mb-4" style="max-width: 350px">
|
<v-flex xs12 sm6 md4>
|
||||||
<v-alert v-if="loggedIn" color="blue-darken-1" icon="mdi-flash">
|
<v-alert :value="loggedIn" type="info">
|
||||||
<h3>Thanks for being a member!</h3>
|
<h4>Thanks for being a member!</h4>
|
||||||
<p>If you need any support with SSO Tools, or with connecting applications using SAML2, please get in touch with us.</p>
|
<p>If you need any support with SSO Tools or with connecting applications using SAML2, please get in touch with us.</p>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
|
|
||||||
<v-alert v-if="!loggedIn" type="warning" >
|
<v-alert :value="!loggedIn" type="warning" >
|
||||||
<h3>Hey! Listen!</h3>
|
<h4>Hey! Listen!</h4>
|
||||||
<p class="mb-4">You're currently using SSO Tools in sandbox mode as a non-member.</p>
|
<p>You're currently using SSO Tools in sandbox mode as a non-member.</p>
|
||||||
<p>This is totally fine, but it means that you'll lose access to any IDPs, SPs, and other settings you create if and when your session ends. Login or create a new account to save your progress.</p>
|
<p>This is totally fine, but it means that you'll lose access to any IDPs, SPs, and other settings you create if and when your session ends. Login or create a new account to save your progress.</p>
|
||||||
<div class="mt-5">
|
<v-btn color="teal" dark v-on:click="register">Create your free account</v-btn>
|
||||||
<v-btn class="mr-2" color="teal" dark v-on:click="register">Register</v-btn>
|
<v-btn v-on:click="login">Login</v-btn>
|
||||||
<v-btn v-on:click="login">Login</v-btn>
|
|
||||||
</div>
|
|
||||||
</v-alert>
|
</v-alert>
|
||||||
</div>
|
</v-flex>
|
||||||
|
|
||||||
|
<v-flex xs12 sm6 md12>
|
||||||
|
|
||||||
|
<v-btn style="float:right;" to='/idps/new' color="primary" v-if="idps.length">Create a new IDP</v-btn>
|
||||||
|
<h2>Your IDPs</h2>
|
||||||
|
<div style="clear:both;" />
|
||||||
|
|
||||||
<div class="flex-grow-1">
|
|
||||||
<div style="text-align:center;margin-top:50px;" v-if="loading">
|
<div style="text-align:center;margin-top:50px;" v-if="loading">
|
||||||
<v-progress-circular indeterminate color="primary" :size="50"></v-progress-circular>
|
<v-progress-circular indeterminate color="primary" :size="50"></v-progress-circular>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!idps.length && !loading" class="text-center">
|
<div v-if="!idps.length && !loading" style="text-align:center;margin-top:50px;">
|
||||||
<h3 class="mb-5">You don't yet have any IdPs</h3>
|
<v-sheet elevation="6">
|
||||||
<v-btn to='/idps/new' color="primary">Create your first IdP</v-btn>
|
<div style="padding: 20px">
|
||||||
<img :src="emptyImage" style="width:100%;max-width:400px;display:block;margin:20px auto;" />
|
<h4>There's nothing out there yet</h4>
|
||||||
|
<v-btn to='/idps/new' color="primary">Get started!</v-btn>
|
||||||
|
|
||||||
|
<img :src="emptyImage" style="width:100%;max-width:400px;display:block;margin:20px auto;" />
|
||||||
|
</div>
|
||||||
|
</v-sheet>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="idps.length">
|
<v-layout row wrap>
|
||||||
<div class="d-flex justify-space-between">
|
<v-flex xs12 sm12 md6 v-for="idp in idps" :key="idp._id" style="padding: 8px;">
|
||||||
<h2>Your IDPs</h2>
|
<v-card :to="`/idps/${idp._id}`">
|
||||||
<v-btn to='/idps/new' color="primary" v-if="idps.length">Create a new IDP</v-btn>
|
<v-card-title primary-title>
|
||||||
</div>
|
<div>
|
||||||
<div class="mt-10 d-flex flex-wrap">
|
<h3 class="headline mb-0">{{idp.name}}</h3>
|
||||||
<div class="w-50 pa-2" v-for="idp in idps" :key="idp._id">
|
<div>https://idp.sso.tools/{{idp.code}}</div>
|
||||||
<v-card :to="`/idps/${idp._id}`">
|
</div>
|
||||||
<v-card-title primary-title>
|
</v-card-title>
|
||||||
<h3 class="headline mb-0">{{idp.name}}</h3>
|
|
||||||
</v-card-title>
|
<v-card-actions>
|
||||||
<v-card-text>https://idp.sso.tools/{{idp.code}}</v-card-text>
|
<v-btn :to="{ path: `/idps/${idp._id}`}" flat color="orange"><v-icon>settings</v-icon> Manage</v-btn>
|
||||||
<v-card-actions>
|
</v-card-actions>
|
||||||
<v-btn :to="`/idps/${idp._id}`" flat color="primary" prepend-icon="mdi-cog">Manage</v-btn>
|
</v-card>
|
||||||
</v-card-actions>
|
</v-flex>
|
||||||
</v-card>
|
</v-layout>
|
||||||
</div>
|
</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
@ -60,7 +65,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import api from '../api';
|
import api from '../api';
|
||||||
import emptyImage from '../assets/empty.png';
|
import emptyImage from '../assets/empty.jpg';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
|
@ -1,117 +1,119 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="bg-indigo-lighten-5">
|
<div class="banner">
|
||||||
<v-container class="d-block d-sm-flex align-center">
|
<div class="banner-background" :style="`background-image:url(${landing});`"/>
|
||||||
<div class="w-auto pa-5">
|
<div class="banner-content">
|
||||||
<h1 class="mb-5">Set-up and test single sign-on in your web, mobile, and desktop apps</h1>
|
<v-container>
|
||||||
<p>With SSO Tools it is easy to spin-up your own custom identity providers, allowing you to start testing your <span class="bg-yellow-lighten-3 rounded-md pa-1">SAML2</span> applications in minutes.</p>
|
<v-layout>
|
||||||
<v-btn class="mt-5" to="/idps/new" color="primary" prepend-icon="mdi-plus"> Create your own IdP</v-btn>
|
<v-flex xs12 md6>
|
||||||
<div class="d-flex align-center mt-2">
|
<h1>Easily set-up and test your single sign-on applications</h1>
|
||||||
<v-icon icon="mdi-star" class="mr-2 text-primary" />
|
|
||||||
<p><small>It's free & you don't have to register an account</small></p>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex align-center mt-1">
|
|
||||||
<v-icon icon="mdi-star" class="mr-2 text-primary" />
|
|
||||||
<p><small>SSO Tools is fully open-source</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-auto">
|
|
||||||
<img v-bind:src="landingImage" class="w-100"/>
|
|
||||||
</div>
|
|
||||||
</v-container>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-container>
|
<h2 style="margin-top:40px;">IdP Manager</h2>
|
||||||
<div class="text-center mt-10 ml-5 mr-5">
|
<p>SSO Tools can quickly spin-up your own custom Identity Providers. Start testing your SAML2 applications in minutes.</p>
|
||||||
<h2>Get confident with your SSO apps</h2>
|
<v-btn to="/idps/new" color="primary"><v-icon>add</v-icon> Create your own IdP</v-btn>
|
||||||
<p>Develop and fully test out your applications with single sign-on to radically improve your offering for <strong>enterprise customers</strong>.</p>
|
<p><small>* It's free & you don't need to register an account</small></p>
|
||||||
<p>SSO Tools is great for small SaaS organisations who need to learn about and <strong>provide federated authentication</strong> to their customers.</p>
|
</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
|
</v-container>
|
||||||
<div class="d-block d-sm-flex ml-5 ml-sm-16 mr-5 mr-sm-16 mt-16">
|
|
||||||
<div class="w-auto mr-5 mb-5">
|
|
||||||
<h2>Quick and simple: we focus on the essentials</h2>
|
|
||||||
<p>Use the SSO Tools sandbox to quickly spin-up identity providers, register users and set-up your service providers in order to test the entire SSO lifecycle.</p>
|
|
||||||
<p>You don't need to worry about signing up for complicated SSO providers, and <strong>you don't even need an account to get started</strong>.</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-auto">
|
|
||||||
<img :src="usersImage" style="width:100%;border-radius:3px;box-shadow:0px 4px 10px rgba(0,0,0,0.2);" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-block d-sm-flex ml-5 ml-sm-16 mr-5 mr-sm-16 mt-16">
|
<v-container grid-list-xl>
|
||||||
<div class="w-auto">
|
<v-layout :justify-center="true">
|
||||||
<img :src="secureImage" style="width:100%;border-radius:3px;box-shadow:0px 4px 10px rgba(0,0,0,0.2);" />
|
<v-flex xs12 sm8 md6 lg4 style="text-align:center;">
|
||||||
</div>
|
<h2>Get confident with your SSO apps</h2>
|
||||||
<div class="w-auto ml-5 mt-5">
|
<p>Develop and fully test out your applications with single sign-on to radically improve your offering for <strong>enterprise customers</strong>.</p>
|
||||||
<h2>Personalised and secure</h2>
|
<p>SSO Tools is great for small SaaS organisations who need to learn about and <strong>provide federated authentication</strong> to their customers.</p>
|
||||||
<p>Each of your identity providers is given its own path at our IdP subdomain, allowing you to easily separate different IdP configurations for testing different functions.</p>
|
</v-flex>
|
||||||
<h2 class="mt-5">Emulate a real-world IdP</h2>
|
</v-layout>
|
||||||
<p>SSO Tools allows you to run a typical IdP environment. Users associated with your provider can locally login to list your connected applications to test the login and logout flows.</p>
|
|
||||||
<p>Support for both IdP and SP initiated sign-on is available, allowing you to test your applications under typical enterprise SSO usage. For example, if one of your customers has a link to sign-in to your app from their local intranet.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-block d-sm-flex ml-5 ml-sm-16 mr-5 mr-sm-16 mt-16">
|
<v-layout style="margin-top:50px;" wrap>
|
||||||
<div class="w-auto mr-5 mb-5">
|
<v-flex xs12 md6>
|
||||||
<h2>Follow industry standards</h2>
|
<h2>Quick and simple: we focus on the essentials</h2>
|
||||||
<p>SSO Tools allows you to test your SSO implementations in your apps following protocols and standards used by the vast majority of large companies, educational institutions, government agencies, and more.</p>
|
<p>Use the SSO Tools sandbox to quickly spin-up identity providers, register users and set-up your service providers in order to test the entire SSO lifecycle.</p>
|
||||||
<p>We currently support the SAML2 protocol, which works well with your customers using LDAP and/or Microsoft Active Directory. Each IdP you create can have different settings to enable you to fully test out your services and your multi-tenancy support.</p>
|
<p>You don't need to worry about signing up for complicated SSO providers, and <strong>you don't even need an account to get started</strong>.</p>
|
||||||
</div>
|
</v-flex>
|
||||||
<div class="w-auto">
|
<v-flex xs12 md6>
|
||||||
<img :src="samlImage" style="width:100%;border-radius:3px;box-shadow:0px 4px 10px rgba(0,0,0,0.2);" />
|
<img :src="usersImage" style="width:100%;border-radius:3px;box-shadow:0px 4px 10px rgba(0,0,0,0.2);" />
|
||||||
</div>
|
</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
|
|
||||||
<div class="d-flex flex-column align-center bg-indigo-lighten-5 mt-16 pa-10 rounded-lg elevation-5">
|
<v-layout style="margin-top:50px;" wrap>
|
||||||
<div class="w-75">
|
<v-flex xs12 md6 order-xs2 order-md1>
|
||||||
<h1>Features & roadmap</h1>
|
<img :src="secureImage" style="width:100%;border-radius:3px;box-shadow:0px 4px 10px rgba(0,0,0,0.2);" />
|
||||||
<p>SSO Tools is offered as a free service. For any questions, or to get in touch, please do so via <a href="mailto:hello@sso.tools" target="_blank" rel="noopener noreferrer">email</a>.</p>
|
</v-flex>
|
||||||
</div>
|
<v-flex xs12 md6 order-xs1 order-md2>
|
||||||
|
<h2>Personalised and secure</h2>
|
||||||
|
<p>Each of your identity providers is given its own path at our IdP subdomain, allowing you to easily separate different IdP configurations for testing different functions.</p>
|
||||||
|
<h2>Emulate a real-world IdP</h2>
|
||||||
|
<p>SSO Tools allows you to run a typical IdP environment. Users associated with your provider can locally login to list your connected applications to test the login and logout flows.</p>
|
||||||
|
<p>Support for both IdP and SP initiated sign-on is available, allowing you to test your applications under typical enterprise SSO usage. For example, if one of your customers has a link to sign-in to your app from their local intranet.</p>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
<div class="d-block d-sm-flex mt-10">
|
<v-layout style="margin-top:50px;" wrap>
|
||||||
<div class="mr-2">
|
<v-flex xs12 md6>
|
||||||
<h3>What you get now</h3>
|
<h2>Follow industry standards</h2>
|
||||||
<v-list>
|
<p>SSO Tools allows you to test your SSO implementations in your apps following protocols and standards used by the vast majority of large companies, educational institutions, government agencies, and more.</p>
|
||||||
<v-list-item v-for="feature in features" :key="feature">
|
<p>We currently support the SAML2 protocol, which works well with your customers using LDAP and/or Microsoft Active Directory. Each IdP you create can have different settings to enable you to fully test out your services and your multi-tenancy support.</p>
|
||||||
<v-list-item-icon><v-icon icon="mdi-check-circle" class="text-green mr-2"/></v-list-item-icon>
|
</v-flex>
|
||||||
<v-list-item-content>
|
<v-flex xs12 md6>
|
||||||
{{ feature }}
|
<img :src="samlImage" style="width:100%;border-radius:3px;box-shadow:0px 4px 10px rgba(0,0,0,0.2);" />
|
||||||
</v-list-item-content>
|
</v-flex>
|
||||||
</v-list-item>
|
</v-layout>
|
||||||
|
|
||||||
|
<h1 style="margin-top:50px;">Features & roadmap</h1>
|
||||||
|
<p>SSO Tools is currently offered as a free service. It is maintained by a single developer for testing SAML2 SSO applications. It's not recommended for production use as there is no offer of guarantee for uptime! For any questions, or to get in touch, please do so via <a href="mailto:hello@sso.tools" target="_blank" rel="noopener noreferrer">email</a>.</p>
|
||||||
|
|
||||||
|
<v-layout wrap>
|
||||||
|
<v-flex sm6>
|
||||||
|
<h2>What you get now</h2>
|
||||||
|
<v-list dense style="margin-top:15px;">
|
||||||
|
<v-list-tile v-for="feature in features" :key="feature" avatar>
|
||||||
|
<v-list-tile-avatar>
|
||||||
|
<v-icon style="color:green;">check_circle</v-icon>
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>{{ feature }}</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
</div>
|
</v-flex>
|
||||||
|
|
||||||
<div class="mt-5 mt-sm-0">
|
<v-flex sm6>
|
||||||
<h3>What's coming</h3>
|
<h2>What's coming</h2>
|
||||||
<v-list>
|
<v-list dense style="margin-top:15px;">
|
||||||
<v-list-item v-for="item in roadmap" :key="item" avatar>
|
<v-list-tile v-for="item in roadmap" :key="item" avatar>
|
||||||
<v-list-item-icon><v-icon icon="mdi-clock-outline" class="text-grey-lighten-1 mr-2" /></v-list-item-icon>
|
<v-list-tile-avatar>
|
||||||
<v-list-item-content>
|
<v-icon style="color:rgb(200,200,200);">access_time</v-icon>
|
||||||
{{ item }}
|
</v-list-tile-avatar>
|
||||||
</v-list-item-content>
|
<v-list-tile-content>
|
||||||
</v-list-item>
|
<v-list-tile-title>{{ item }}</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
</div>
|
</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-10 d-flex justify-center">
|
<div style="margin: 50px 0px;"><v-divider /></div>
|
||||||
<div class="w-75">
|
|
||||||
<h1 class="mb-8">👋 Hi there, thanks for visiting</h1>
|
|
||||||
<p class="mb-2">SSO Tools is created and maintained by a solo developer. During my work as part of a growing startup selling enterprise SaaS, the need for providing larger organisations with federated authentication became hugely important.</p>
|
<v-layout :justify-center="true">
|
||||||
<p class="mb-2">I spent a lot of my spare time reading-up and learning about the different approaches to SSO via SAML2, with a focus on security whilst also making set-up easy for our customers.</p>
|
<v-flex xs12 sm10 md8 lg6>
|
||||||
<p class="mb-2">In my spare time I began working on SSO Tools so that I could easily test sign-on and logout flows across different use-cases.</p>
|
<h1>👋 Hi there, thanks for visiting</h1>
|
||||||
<p class="mb-2">SSO Tools is free and open-source software, and you can <a href='https://git.wilw.dev/wilw/sso-tools' target='_blank' rel='noopener noreferrer'>check out the source code</a> if you are interested. <strong>I hope you find it useful!</strong></p>
|
<p>SSO Tools is created and maintained by a solo developer. During my work as part of a growing startup selling enterprise SaaS, the need for providing larger organisations with federated authentication became hugely important.</p>
|
||||||
</div>
|
<p>I spent a lot of my spare time reading-up and learning about the different approaches to SSO via SAML2, with a focus on security whilst also making set-up easy for our customers.</p>
|
||||||
</div>
|
<p>In my spare time I began working on SSO Tools so that I could easily test sign-on and logout flows across different use-cases.</p>
|
||||||
|
<p>SSO Tools is free and open-source software, and you can <a href='https://git.wilw.dev/wilw/sso-tools' target='_blank' rel='noopener noreferrer'>check out the source code</a> if you are interested. <strong>I hope you find it useful!</strong></p>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import landingImage from '../assets/login.png';
|
import landing from '../assets/landing.png';
|
||||||
import usersImage from '../assets/users.png';
|
import usersImage from '../assets/users.png';
|
||||||
import secureImage from '../assets/secure.png';
|
import secureImage from '../assets/secure.png';
|
||||||
import samlImage from '../assets/saml.png';
|
import samlImage from '../assets/saml.png';
|
||||||
@ -120,7 +122,7 @@ export default {
|
|||||||
name: 'Home',
|
name: 'Home',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
landingImage, usersImage, secureImage, samlImage,
|
landing, usersImage, secureImage, samlImage,
|
||||||
features: [
|
features: [
|
||||||
'Account-less sandbox', 'Create unlimited IdPs', 'Register apps/SPs with your IdPs', 'Register users with your IdPs', 'Support for custom user attributes', 'Support for specifying custom attribute mappings', 'IdP authentication', 'IdP- and SP-initiated SAML2 sign-on', 'SAML2 ForceAuthn respected', 'SP-initiated log-out'
|
'Account-less sandbox', 'Create unlimited IdPs', 'Register apps/SPs with your IdPs', 'Register users with your IdPs', 'Support for custom user attributes', 'Support for specifying custom attribute mappings', 'IdP authentication', 'IdP- and SP-initiated SAML2 sign-on', 'SAML2 ForceAuthn respected', 'SP-initiated log-out'
|
||||||
],
|
],
|
||||||
@ -158,6 +160,7 @@ export default {
|
|||||||
|
|
||||||
}
|
}
|
||||||
.banner-content{
|
.banner-content{
|
||||||
position: relative;
|
position:relative;
|
||||||
|
min-height:300px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,50 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<v-container>
|
<v-container grid-list-lg>
|
||||||
<h3>Manage Identity Provider</h3>
|
<h3>Manage Identity Provider</h3>
|
||||||
<h1 class="mb-10">{{idp && idp.name}}</h1>
|
<h1 style="margin-bottom:30px">{{idp && idp.name}}</h1>
|
||||||
|
|
||||||
<div class="d-block d-sm-flex">
|
<v-layout wrap>
|
||||||
<div class="mb-10">
|
<v-flex md4 xs12>
|
||||||
<v-card v-if="idp">
|
<v-card>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item exact :to="`/idps/${idp._id}`" prepend-icon="mdi-home">
|
<v-list-tile exact :to="`/idps/${idp._id}`">
|
||||||
<v-list-item-content>Overview</v-list-item-content>
|
<v-list-tile-action>
|
||||||
</v-list-item>
|
<v-icon>home</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Overview</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
<v-list-item :to="`/idps/${idp._id}/settings`" prepend-icon="mdi-cogs">
|
<v-list-tile :to="`/idps/${idp._id}/settings`">
|
||||||
<v-list-item-content>Settings</v-list-item-content>
|
<v-list-tile-action>
|
||||||
</v-list-item>
|
<v-icon>settings</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Settings</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
<v-list-item :to="`/idps/${idp._id}/users`" prepend-icon="mdi-account-group">
|
<v-list-tile :to="`/idps/${idp._id}/users`">
|
||||||
<v-list-item-content>Users</v-list-item-content>
|
<v-list-tile-action>
|
||||||
</v-list-item>
|
<v-icon>people</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Users</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
<v-list-item :to="`/idps/${idp._id}/sps`" prepend-icon="mdi-power-plug">
|
<v-list-tile :to="`/idps/${idp._id}/sps`">
|
||||||
<v-list-item-content>Connected apps</v-list-item-content>
|
<v-list-tile-action>
|
||||||
</v-list-item>
|
<v-icon>extension</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Connected apps</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
|
|
||||||
<v-list-item :to="`/idps/${idp._id}/saml`" prepend-icon="mdi-swap-horizontal">
|
<v-list-tile :to="`/idps/${idp._id}/saml`">
|
||||||
<v-list-item-content>SAML2 configuration</v-list-item-content>
|
<v-list-tile-action>
|
||||||
</v-list-item>
|
<v-icon>compare_arrows</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
<v-list-item :to="`/idps/${idp._id}/logs`" prepend-icon="mdi-format-list-bulleted">
|
<v-list-tile-content>
|
||||||
<v-list-item-content>SAML2 logs</v-list-item-content>
|
<v-list-tile-title>SAML2 configuration</v-list-tile-title>
|
||||||
</v-list-item>
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile :to="`/idps/${idp._id}/logs`">
|
||||||
|
<v-list-tile-action>
|
||||||
|
<v-icon>format_list_bulleted</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>SAML2 logs</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-btn block class="mt-5" :href="`https://idp.sso.tools/${idp?.code}`" target="_blank" prepend-icon="mdi-open-in-new">Open IdP dashboard</v-btn>
|
<v-btn block color='secondary' style="margin-top: 15px;" :href="`https://idp.sso.tools/${idp.code}`" target="_blank"><v-icon>open_in_new</v-icon> Open IdP dashboard</v-btn>
|
||||||
</div>
|
</v-flex>
|
||||||
|
|
||||||
<div class="ml-sm-5" style="flex: 1">
|
<v-flex md8>
|
||||||
<div v-if="idp">
|
<div v-if="idp">
|
||||||
<router-view :idp="idp" @onUpdateIdp="updateIdp"/>
|
<router-view :idp="idp"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
|
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
@ -67,9 +96,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateIdp(upd) {
|
|
||||||
this.idp = upd;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<v-card-text>
|
<v-card-text>
|
||||||
<h5>IDP host</h5>
|
<h5>IDP host</h5>
|
||||||
<p>The URL of your IDP on the Internet. This forms the basis of your <router-link :to="`/idps/${idp._id}/saml`">SSO configuration</router-link>.</p>
|
<p>The URL of your IDP on the Internet. This forms the basis of your <router-link :to="`/idps/${idp._id}/saml`">SSO configuration</router-link>.</p>
|
||||||
<v-text-field :model-value="`https://idp.sso.tools/${idp.code}`" label="IDP host" variant="solo" readonly/>
|
<v-text-field :value="`https://idp.sso.tools/${idp.code}`" label="IDP host" readonly/>
|
||||||
|
|
||||||
<h5>SAML2 configuration</h5>
|
<h5>SAML2 configuration</h5>
|
||||||
<v-btn :to='`/idps/${idp._id}/saml`'>See SAML2 configuration</v-btn>
|
<v-btn :to='`/idps/${idp._id}/saml`'>See SAML2 configuration</v-btn>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<v-card-title primary-title><h3>Delete IDP</h3></v-card-title>
|
<v-card-title primary-title><h3>Delete IDP</h3></v-card-title>
|
||||||
<v-card-text>Deleting this IDP will immediately and irreversibly remove the Identity Provider, its registered Service Providers, and any users associated with the IDP.</v-card-text>
|
<v-card-text>Deleting this IDP will immediately and irreversibly remove the Identity Provider, its registered Service Providers, and any users associated with the IDP.</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn v-on:click="deleteIDP" color='red'>Delete</v-btn>
|
<v-btn v-on:click="deleteIDP" color='warning'>Delete</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ export default {
|
|||||||
deleteConfirm (event) {
|
deleteConfirm (event) {
|
||||||
this.deletingProgress = true;
|
this.deletingProgress = true;
|
||||||
api.req('DELETE', `/idps/${this.$route.params.id}`, null, resp => {
|
api.req('DELETE', `/idps/${this.$route.params.id}`, null, resp => {
|
||||||
this.deletingProgress = false;
|
this.deletingProgress = false;
|
||||||
this.deleting = false;
|
this.deleting = false;
|
||||||
this.$router.push('/dashboard');
|
this.$router.push('/dashboard');
|
||||||
}, err => {
|
}, err => {
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p>Below you'll find the latest requests and responses logged by SSOTools for your IdP. Requests are logged in JSON format and are encoded into XML for SAML2 transport.</p>
|
<p>Below you'll find the latest requests and responses logged by SSOTools for your IdP. Requests are logged in JSON format and are encoded into XML for SAML2 transport.</p>
|
||||||
<v-alert class="mt-5" type="info">Checking the logs can be useful in debugging your SSO setup. You can use it to compare against what you are sending or receiving in your application.</v-alert>
|
<v-alert :value="true" type="info">Checking the logs can be useful in debugging your SSO setup. You can use it to compare against what you are sending or receiving in your application.</v-alert>
|
||||||
|
|
||||||
<v-btn v-on:click="fetchLogs" class="mt-10 mb-5" prepend-icon="mdi-refresh">Refresh logs</v-btn>
|
<v-btn v-on:click="fetchLogs" style="margin: 10px 0px;"><v-icon>refresh</v-icon> Refresh logs</v-btn>
|
||||||
|
|
||||||
<v-alert v-if="!logs.length" :value="true" border="left" color="blue-grey" dark>No requests have been logged against this IdP yet.</v-alert>
|
<v-alert v-if="!logs.length" :value="true" border="left" color="blue-grey" dark>No requests have been logged against this IdP yet.</v-alert>
|
||||||
|
|
||||||
<v-card v-for="log in logs" :key="log._id" style="padding: 5; margin-bottom: 15px">
|
<v-card v-for="log in logs" :key="log._id" style="padding: 5; margin-bottom: 15px">
|
||||||
<v-card-title>
|
<v-card-title primary-title>
|
||||||
<div class="d-flex justify-space-between">
|
<v-layout row wrap style="font-weight: bold;">
|
||||||
<p class="mr-2">{{formatDate(log.createdAt)}}</p>
|
<v-flex xs6 sm6 md4>{{formatDate(log.createdAt)}}</v-flex>
|
||||||
<p class="mr-2">{{log.spName || log.sp}}</p>
|
<v-flex xs6 sm6 md4>{{log.spName || log.sp}}</v-flex>
|
||||||
<p>{{log.type}}</p>
|
<v-flex xs6 sm6 md4>{{log.type}}</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<textarea readonly rows="10" style="width: 100%; font-size: 8; font-family: monospace;" v-model="log.formattedData" />
|
<textarea readonly rows="10" style="width: 100%; font-size: 8; font-family: monospace;" v-model="log.formattedData" />
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p>You can use the details below to configure your SAML2-compatibile service providers to use this IDP as an identity source.</p>
|
<p>You can use the details below to configure your SAML2-compatibile service providers to use this IDP as an identity source.</p>
|
||||||
<v-alert type="info" class="mt-5">To start using a service provider with this IDP you will also need to register it on the <router-link style="color:white;" :to="`/idps/${idp._id}/sps`">Connected apps</router-link> page.</v-alert>
|
<v-alert :value="true" type="info">To start using a service provider with this IDP you will also need to register it on the <router-link style="color:white;" :to="`/idps/${idp._id}/sps`">Service Providers</router-link> page.</v-alert>
|
||||||
|
|
||||||
<div style="margin-top:20px;" />
|
<div style="margin-top:20px;" />
|
||||||
<v-text-field readonly label="Sign-on URL (single login service through the HTTP redirect binding)" :model-value="`https://idp.sso.tools/${idp.code}/saml/login/request`" />
|
<v-text-field readonly label="Sign-on URL (single login service through the HTTP redirect binding)" :value="`https://idp.sso.tools/${idp.code}/saml/login/request`" />
|
||||||
<v-text-field readonly label="Logout URL (single logout service through the HTTP redirect binding)" :model-value="`https://idp.sso.tools/${idp.code}/saml/logout/request`" />
|
<v-text-field readonly label="Logout URL (single logout service through the HTTP redirect binding)" :value="`https://idp.sso.tools/${idp.code}/saml/logout/request`" />
|
||||||
<v-textarea :model-value="idp.saml.certificate" label="Signing certificate" readonly rows="6" style="font-size:11px;"/>
|
<v-textarea :value="idp.saml.certificate" label="Signing certificate" readonly rows="6" style="font-size:11px;"/>
|
||||||
<v-alert type="info" class="mt-5">
|
<v-alert :value="true" type="info">
|
||||||
<h4>Self-signed certificates</h4>
|
<h4>Self-signed certificates</h4>
|
||||||
<p>Please note that SSO Tools only issues self-signed certificates. This means that you may need to turn off signature validation on your service provider.</p>
|
<p>Please note that SSO Tools only issues self-signed certificates. This means that you may need to turn off signature validation on your service provider.</p>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
@ -25,7 +25,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h3>Friendly name</h3>
|
<p>Configure your identity provider.</p>
|
||||||
|
<div style="clear:both;margin-bottom: 20px;" />
|
||||||
|
|
||||||
|
<h5>Friendly name</h5>
|
||||||
<p>This is the name given to your IDP so that you can recognise it. It's also the name shown to <router-link :to="`/idps/${idp._id}/users`">users who authenticate against this IDP</router-link>.</p>
|
<p>This is the name given to your IDP so that you can recognise it. It's also the name shown to <router-link :to="`/idps/${idp._id}/users`">users who authenticate against this IDP</router-link>.</p>
|
||||||
<v-text-field v-model="idp.name" label="Friendly name"/>
|
<v-text-field v-model="idp.name" label="Friendly name"/>
|
||||||
|
|
||||||
<h3>Code (issuer)</h3>
|
<h5>Code (issuer)</h5>
|
||||||
<p>A globally unique machine-friendly (alphanumeric) code to identify this IDP on SSO Tools. We derive the issuer and other SSO information from this code, so you may need to update other configurations elsewhere if you do change it.</p>
|
<p>A globally unique machine-friendly (i.e. [a-ZA-Z0-9]) code to identify this IDP on SSO Tools. We derive the issuer and other SSO information from this code, so you may need to update other configurations elsewhere if you do change it.</p>
|
||||||
<v-text-field v-model="idp.code" label="Code" />
|
<v-text-field v-model="idp.code" label="Code" />
|
||||||
|
|
||||||
<v-btn color='primary' :loading="saving" v-on:click="save">Save changes</v-btn>
|
<v-btn color='primary' :loading="saving" v-on:click="save">Save changes</v-btn>
|
||||||
@ -32,7 +35,7 @@ export default {
|
|||||||
const data = { name, code };
|
const data = { name, code };
|
||||||
this.saving = true;
|
this.saving = true;
|
||||||
api.req('PUT', `/idps/${this.idp._id}`, { name, code }, resp => {
|
api.req('PUT', `/idps/${this.idp._id}`, { name, code }, resp => {
|
||||||
this.$emit('onUpdateIdp', resp);
|
this.idp = resp;
|
||||||
this.snackbar = true;
|
this.snackbar = true;
|
||||||
this.saving = false;
|
this.saving = false;
|
||||||
}, err => {
|
}, err => {
|
||||||
|
@ -1,70 +1,74 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p>Register an app (e.g. your website or mobile app) here in order to connect it to your IdP.</p>
|
<h2>Apps connected to your IdP</h2>
|
||||||
|
<p>If you are creating a single sign-on facility in your application you can register it as a service provider here in order to test the connection.</p>
|
||||||
|
|
||||||
<v-alert class="mt-5" icon="mdi-information">Users registered with this IdP will only be able to access the apps listed below.</v-alert>
|
<v-alert :value="true" type="info">Users registered with this IdP will only be able to access the apps regisered below.</v-alert>
|
||||||
|
|
||||||
<div class="d-flex justify-end mt-5 mb-b">
|
<v-btn color='primary' style="float:right;" v-on:click="openDialog"><v-icon>add</v-icon> Register a new SP</v-btn>
|
||||||
<v-btn color='primary' v-on:click="openDialog" prepend-icon="mdi-plus">New app</v-btn>
|
<div style="clear:both;margin-bottom: 20px;" />
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-table :items="sps" v-if="sps.length">
|
<v-data-table :loading="loadingSps" hide-actions class="elevation-1" :headers="tableHeaders" :items="sps">
|
||||||
<thead>
|
<template v-slot:items="props">
|
||||||
<tr>
|
<td>{{props.item.name}}</td>
|
||||||
<th>App name</th>
|
<td>
|
||||||
<th>Configuration</th>
|
EntityID: {{props.item.entityId}}<br />
|
||||||
<th />
|
Service: {{props.item.serviceUrl}}<br />
|
||||||
</tr>
|
Consumer: {{props.item.callbackUrl}}<br />
|
||||||
</thead>
|
Logout: {{props.item.logoutUrl}}<br />
|
||||||
<tbody>
|
Logout callback: {{props.item.logoutCallbackUrl}}
|
||||||
<tr v-for="app in sps" key="app._id">
|
</td>
|
||||||
<td>{{app.name}} <br />
|
<td>
|
||||||
<span class="text-grey">{{app.serviceUrl}}</span>
|
<v-menu offset-y transition="slide-y-transition">
|
||||||
</td>
|
<template v-slot:activator="{ on }">
|
||||||
<td>
|
<v-icon small class="mr-2" v-on="on">settings</v-icon>
|
||||||
<span v-if="app.entityId">EntityID: {{app.entityId}}</span>
|
</template>
|
||||||
<span v-if="app.callbackUrl"><br />Consumer: {{app.callbackUrl}}</span>
|
<v-list>
|
||||||
<span v-if="app.logoutUrl"><br />Logout: {{app.logoutUrl}}</span>
|
<v-list-tile v-on:click="e => editSp(props.item)">
|
||||||
<span v-if="app.logoutCallbackUrl"><br />Logout callback: {{app.logoutCallbackUrl}}</span>
|
<v-list-tile-title><v-icon>edit</v-icon> Update</v-list-tile-title>
|
||||||
</td>
|
</v-list-tile>
|
||||||
<td>
|
<v-list-tile v-on:click="e => deleteSp(props.item._id)">
|
||||||
<v-btn flat>
|
<v-list-tile-title><v-icon>delete</v-icon> Delete</v-list-tile-title>
|
||||||
Manage
|
</v-list-tile>
|
||||||
<v-menu activator="parent">
|
</v-list>
|
||||||
<v-list>
|
</v-menu>
|
||||||
<v-list-item v-on:click="e => editSp(app)" prepend-icon="mdi-pencil">
|
</td>
|
||||||
<v-list-item-content>Update</v-list-item-content>
|
</template>
|
||||||
</v-list-item>
|
</v-data-table>
|
||||||
<v-list-item v-on:click="e => deleteSp(app._id)" prepend-icon="mdi-delete">
|
|
||||||
<v-list-item-content>Delete</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
</v-btn>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</v-table>
|
|
||||||
|
|
||||||
<v-dialog v-model="dialog" persistent max-width="600px">
|
<v-dialog v-model="dialog" persistent max-width="600px">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
<span class="headline">{{editing ? 'Edit app': 'Register an app for use with this IDP'}}</span>
|
<span class="headline">{{editing ? 'Edit Service Provider': 'Register a Service Provider for use with this IDP'}}</span>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-text-field class="mb-2" label="Human-readable name" required autofocus v-model="newSP.name" hint="To help you identify this app." placeholder="My Service"/>
|
<v-container grid-list-md>
|
||||||
<v-text-field class="mb-2" label="Service URL" v-model="newSP.serviceUrl" hint="The URL used to access your service. For example, for a webapp, you can just use your website URL." placeholder="https://sp.example.com"/>
|
<v-layout wrap>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
<h3 class="mb-2">SAML2 settings (optional)</h3>
|
<v-text-field label="Friendly name" required autofocus v-model="newSP.name" hint="To help you identify this SP." placeholder="My Service"/>
|
||||||
<v-text-field class="mb-2" label="EntityID" v-model="newSP.entityId" hint="This is a URL to uniquely identify your service. It is sometimes the same as the metadata URL." placeholder="https://sp.example.com/metdadata"/>
|
</v-flex>
|
||||||
<v-text-field class="mb-2" label="ACS URL" v-model="newSP.callbackUrl" hint="Assertion Consumer Service, or callback URL using the HTTP POST binding." placeholder="https://sp.example.com/callback"/>
|
<v-flex xs12 sm6>
|
||||||
<v-text-field class="mb-2" label="Logout URL" v-model="newSP.logoutUrl" hint="The URL we will redirect IDP-initiated logout requests to." placeholder="https://sp.example.com/logout"/>
|
<v-text-field label="Service URL" v-model="newSP.serviceUrl" hint="The URL used to access your service. For example, for a webapp, you can just use your website URL." placeholder="https://sp.example.com"/>
|
||||||
<v-text-field label="Logout callback URL" v-model="newSP.logoutCallbackUrl" hint="The URL we will redirect users to after an SP-initiated logout." placeholder="https://sp.example.com/logout/callback"/>
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="EntityID" v-model="newSP.entityId" hint="This is a URL to uniquely identify your service. It is sometimes the same as the metadata URL." placeholder="https://sp.example.com/metdadata"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="ACS URL" v-model="newSP.callbackUrl" hint="Assertion Consumer Service, or callback URL using the HTTP POST binding." placeholder="https://sp.example.com/callback"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Logout URL (optional)" v-model="newSP.logoutUrl" hint="The URL we will redirect IDP-initiated logout requests to." placeholder="https://sp.example.com/logout"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Logout callback URL (optional)" v-model="newSP.logoutCallbackUrl" hint="The URL we will redirect users to after an SP-initiated logout." placeholder="https://sp.example.com/logout/callback"/>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn @click="dialog = false">Cancel</v-btn>
|
<v-btn color="blue darken-1" flat @click="dialog = false">Cancel</v-btn>
|
||||||
<v-btn color="primary" @click="create">{{editing ? 'Save': 'Create'}}</v-btn>
|
<v-btn color="blue darken-1" flat @click="create">{{editing ? 'Save': 'Create'}}</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
@ -1,148 +1,134 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<v-card>
|
<h2>User accounts</h2>
|
||||||
<v-card-title primary-title><h3>User accounts</h3></v-card-title>
|
<p>Manage the user accounts in this IdP. These users can authenticate against this IdP as part of a single sign-on flow.</p>
|
||||||
<v-card-text>
|
<p>Note that you will not be able to authenticate against this IdP using your SSO Tools account. You can safely use dummy names/emails here (e.g. "name@example.com"). Auto-generated users are given the default password <code>password</code>.</p>
|
||||||
<p class="mb-2">These users can authenticate against this IdP as part of a single sign-on flow.</p>
|
|
||||||
<v-alert icon='mdi-information'>
|
|
||||||
<p><small>Note that you will not be able to authenticate against this IdP using your own SSO Tools account. You can safely use dummy names/emails here (e.g. "name@example.com"). Auto-generated users are given the default password <code>password</code>.</small></p>
|
|
||||||
</v-alert>
|
|
||||||
|
|
||||||
<div class="d-flex justify-end mt-5 mb-b">
|
<v-btn color='primary' style="float:right;" v-on:click="openDialog"><v-icon>add</v-icon> Register a new user</v-btn>
|
||||||
<v-btn color='primary' v-on:click="openDialog" prepend-icon="mdi-plus">New user</v-btn>
|
<div style="clear:both;margin-bottom: 20px;" />
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-table :loading="loadingUsers" v-if="users.length">
|
<v-data-table :loading="loadingUsers" hide-actions class="elevation-1" :headers="tableHeaders" :items="users">
|
||||||
<thead>
|
<template v-slot:items="props">
|
||||||
<tr>
|
<td>{{props.item.firstName}}</td>
|
||||||
<th>Name</th>
|
<td>{{props.item.lastName}}</td>
|
||||||
<th>Email</th>
|
<td>{{props.item.email}}</td>
|
||||||
<th class="text-right"/>
|
<td>
|
||||||
</tr>
|
<v-menu offset-y transition="slide-y-transition">
|
||||||
</thead>
|
<template v-slot:activator="{ on }">
|
||||||
<tbody>
|
<v-icon small class="mr-2" v-on="on">settings</v-icon>
|
||||||
<tr v-for="user in users" key="user._id">
|
</template>
|
||||||
<td>{{user.firstName}} {{user.lastName}}</td>
|
<v-list>
|
||||||
<td>{{user.email}}</td>
|
<v-list-tile v-on:click="e => editUser(props.item)">
|
||||||
<td>
|
<v-list-tile-title><v-icon>edit</v-icon> Update</v-list-tile-title>
|
||||||
<v-btn flat>
|
</v-list-tile>
|
||||||
Manage
|
<v-list-tile v-on:click="e => deleteUser(props.item._id)">
|
||||||
<v-menu activator="parent">
|
<v-list-tile-title><v-icon>delete</v-icon> Delete</v-list-tile-title>
|
||||||
<v-list>
|
</v-list-tile>
|
||||||
<v-list-item v-on:click="e => editUser(user)" prepend-icon="mdi-pencil">
|
</v-list>
|
||||||
<v-list-item-content>Update</v-list-item-content>
|
</v-menu>
|
||||||
</v-list-item>
|
</td>
|
||||||
<v-list-item v-on:click="e => deleteUser(user._id)" prepend-icon="mdi-delete">
|
</template>
|
||||||
<v-list-item-content>Delete</v-list-item-content>
|
</v-data-table>
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
</v-btn>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</v-table>
|
|
||||||
|
|
||||||
<v-dialog v-model="dialog" persistent max-width="600px">
|
<v-dialog v-model="dialog" persistent max-width="600px">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
<span class="headline">{{editing ? 'Edit user' : 'Create a new user'}}</span>
|
<span class="headline">{{editing ? 'Edit user' : 'Create a new user'}}</span>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div class="d-flex">
|
<v-container grid-list-md>
|
||||||
<v-text-field class="mr-2" label="First name" required autofocus v-model="newUser.firstName"/>
|
<v-layout wrap>
|
||||||
<v-text-field class="mr-2" label="Last name" v-model="newUser.lastName" />
|
<v-flex xs12 sm6>
|
||||||
</div>
|
<v-text-field label="First name" required autofocus v-model="newUser.firstName"/>
|
||||||
<div class="d-flex">
|
</v-flex>
|
||||||
<v-text-field class="mr-2" type="email" label="Email address" v-model="newUser.email" />
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Last name" v-model="newUser.lastName" />
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field type="email" label="Email address" v-model="newUser.email" />
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
<v-text-field type="password" label="Password" hint="This can be changed later." v-model="newUser.password" />
|
<v-text-field type="password" label="Password" hint="This can be changed later." v-model="newUser.password" />
|
||||||
</div>
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
<div v-if="attributes.length" class="mt-10">
|
<div v-if="attributes.length">
|
||||||
<h3>Additional user attributes</h3>
|
<h3>Extra attributes</h3>
|
||||||
<p>Specifying a value for an attribute below will include that value in assertions made during the SSO process, overriding the attribute's default value. Leave a value blank to send the default attribute value instead.</p>
|
<p>Specifying a value for an attribute below will include that value in assertions made during the SSO process, overriding the attribute's default value. Leave values here blank to send the default attribute value instead.</p>
|
||||||
|
|
||||||
<div class="d-flex flex-wrap mt-5">
|
<v-layout>
|
||||||
<div class="mr-2 w-25" v-for="attribute in attributes">
|
<v-flex xs12 sm6 v-for="attribute in attributes">
|
||||||
<v-text-field :label="attribute.name" :hint="`Default value: ${attribute.defaultValue ? `'${attribute.defaultValue}'` : 'none'}`" v-model="newUser.attributes[attribute._id]" />
|
<v-text-field :label="attribute.name" :hint="`Default value: ${attribute.defaultValue ? `'${attribute.defaultValue}'` : 'none'}`" v-model="newUser.attributes[attribute._id]" />
|
||||||
</div>
|
</v-flex>
|
||||||
</div>
|
</v-layout>
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-container>
|
||||||
<v-card-actions>
|
</v-card-text>
|
||||||
<v-spacer></v-spacer>
|
<v-card-actions>
|
||||||
<v-btn @click="dialog = false">Cancel</v-btn>
|
<v-spacer></v-spacer>
|
||||||
<v-btn color="primary" dark @click="create">{{editing ? 'Save' : 'Create'}}</v-btn>
|
<v-btn color="blue darken-1" flat @click="dialog = false">Cancel</v-btn>
|
||||||
</v-card-actions>
|
<v-btn color="blue darken-1" dark @click="create">{{editing ? 'Save' : 'Create'}}</v-btn>
|
||||||
</v-card>
|
</v-card-actions>
|
||||||
</v-dialog>
|
</v-card>
|
||||||
</v-card-text>
|
</v-dialog>
|
||||||
</v-card>
|
|
||||||
|
|
||||||
<v-card class="mt-10">
|
<h2 style="margin-top:30px;">Extra attributes</h2>
|
||||||
<v-card-title primary-title><h3>Additional user attributes</h3></v-card-title>
|
<p>Manage custom attributes that can be passed to the Service Provider during sign-on.</p>
|
||||||
<v-card-text>
|
<v-btn color='primary' style="float:right;" v-on:click="openAttributeDialog"><v-icon>add</v-icon> New attribute</v-btn>
|
||||||
<p class="mb-2">Manage custom attributes that can be passed to the Service Provider during sign-on. These attributes are in addition to the core user account attributes (such as first name, last name, and email address).</p>
|
<div style="clear:both;margin-bottom: 20px;" />
|
||||||
|
|
||||||
<div class="d-flex justify-end mt-5 mb-b">
|
<v-data-table :loading="loadingAttributes" hide-actions class="elevation-1" :headers="attributeTableHeaders" :items="attributes">
|
||||||
<v-btn color='primary' v-on:click="openAttributeDialog" prepend-icon="mdi-plus">New attribute</v-btn>
|
<template v-slot:items="props">
|
||||||
</div>
|
<td>{{props.item.name}}</td>
|
||||||
|
<td>{{props.item.defaultValue}}</td>
|
||||||
|
<td>{{props.item.samlMapping}}</td>
|
||||||
|
<td>
|
||||||
|
<v-menu offset-y transition="slide-y-transition">
|
||||||
|
<template v-slot:activator="{ on }">
|
||||||
|
<v-icon small class="mr-2" v-on="on">settings</v-icon>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-tile v-on:click="e => editAttribute(props.item)">
|
||||||
|
<v-list-tile-title><v-icon>edit</v-icon> Update</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile v-on:click="e => deleteAttribute(props.item._id)">
|
||||||
|
<v-list-tile-title><v-icon>delete</v-icon> Delete</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
|
||||||
<v-table :loading="loadingAttributes">
|
<v-dialog v-model="attributeDialog" persistent max-width="600px">
|
||||||
<thead>
|
<v-card>
|
||||||
<tr>
|
<v-card-title>
|
||||||
<th>Human name</th>
|
<span class="headline">{{editingAttribute ? 'Edit attribute' : 'Create a new custom attribute'}}</span>
|
||||||
<th>Attribute key</th>
|
</v-card-title>
|
||||||
<th>Default value</th>
|
<v-card-text>
|
||||||
<th />
|
<v-container grid-list-md>
|
||||||
</tr>
|
<v-layout wrap>
|
||||||
</thead>
|
<v-flex xs12 sm6>
|
||||||
<tbody>
|
<v-text-field label="Name" required autofocus v-model="newAttribute.name" hint="We'll use this as the attribute name in the assertion unless a mapping is provided." />
|
||||||
<tr v-for="attribute in attributes" key="attribute._id">
|
</v-flex>
|
||||||
<td>{{attribute.name}}</td>
|
<v-flex xs12 sm6>
|
||||||
<td>{{attribute.samlMapping}}</td>
|
|
||||||
<td>{{attribute.defaultValue}}</td>
|
|
||||||
<td>
|
|
||||||
<v-btn flat>
|
|
||||||
Manage
|
|
||||||
<v-menu activator="parent">
|
|
||||||
<v-list>
|
|
||||||
<v-list-item v-on:click="e => editAttribute(attribute)" prepend-icon="mdi-pencil">
|
|
||||||
<v-list-item-content>Update</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item v-on:click="e => deleteAttribute(attribute._id)" prepend-icon="mdi-delete">
|
|
||||||
<v-list-item-content>Delete</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
</v-btn>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</v-table>
|
|
||||||
|
|
||||||
<v-dialog v-model="attributeDialog" persistent max-width="600px">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
<span class="headline">{{editingAttribute ? 'Edit attribute' : 'Create a new custom attribute'}}</span>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<div class="dd-flex">
|
|
||||||
<v-text-field class="mb-2" label="Human-readable name" required autofocus v-model="newAttribute.name" hint="We'll use this as the attribute key unless a mapping is provided." />
|
|
||||||
<v-text-field class="mb-2" label="Attribute key" v-model="newAttribute.samlMapping" hint="Values for this attribute will be sent with this key during the SSO process." />
|
|
||||||
<v-text-field label="Default value" v-model="newAttribute.defaultValue" hint="If not overridden in the user itself, this value will be sent as a default."/>
|
<v-text-field label="Default value" v-model="newAttribute.defaultValue" hint="If not overridden in the user itself, this value will be sent as a default."/>
|
||||||
</div>
|
</v-flex>
|
||||||
</v-card-text>
|
<v-flex xs12 sm6>
|
||||||
<v-card-actions>
|
<v-text-field label="SAML2 mapping (optional)" v-model="newAttribute.samlMapping" hint="If provided, we'll label the attribute value with this name in SAML2 assertions." />
|
||||||
<v-spacer></v-spacer>
|
</v-flex>
|
||||||
<v-btn @click="attributeDialog = false">Cancel</v-btn>
|
</v-layout>
|
||||||
<v-btn color="primary" @click="createAttribute">{{editingAttribute ? 'Save' : 'Create'}}</v-btn>
|
</v-container>
|
||||||
</v-card-actions>
|
</v-card-text>
|
||||||
</v-card>
|
<v-card-actions>
|
||||||
</v-dialog>
|
<v-spacer></v-spacer>
|
||||||
</v-card-text>
|
<v-btn color="blue darken-1" flat @click="attributeDialog = false">Cancel</v-btn>
|
||||||
</v-card>
|
<v-btn color="blue darken-1" dark @click="createAttribute">{{editingAttribute ? 'Save' : 'Create'}}</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<v-container>
|
<v-container>
|
||||||
|
|
||||||
|
<v-layout style="margin-top: 50px;" :justify-center="true">
|
||||||
|
<v-flex xs12 md8>
|
||||||
|
|
||||||
<div v-if="page === 0">
|
<div v-if="page === 0">
|
||||||
<div style="text-align:center; margin-bottom: 30px;">
|
<div style="text-align:center; margin-bottom: 30px;">
|
||||||
@ -23,7 +25,7 @@
|
|||||||
<p>You're currently in the SSO Tools sandbox, which means that if you end your browser session you'll lose access to your IdP. If you want to come back to continue working on this IdP at a later date, we recommend creating an account to secure it and to save your progress.</p>
|
<p>You're currently in the SSO Tools sandbox, which means that if you end your browser session you'll lose access to your IdP. If you want to come back to continue working on this IdP at a later date, we recommend creating an account to secure it and to save your progress.</p>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
|
|
||||||
<v-alert type="error" v-if="error">
|
<v-alert type="error" :value="error">
|
||||||
<h3>Could not create IdP</h3>
|
<h3>Could not create IdP</h3>
|
||||||
<p>{{error}}</p>
|
<p>{{error}}</p>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
@ -39,49 +41,75 @@
|
|||||||
<p>Register a user with {{name}}. This user will be able to login via your IdP and access your connected apps.</p>
|
<p>Register a user with {{name}}. This user will be able to login via your IdP and access your connected apps.</p>
|
||||||
<p>You can always add more users later.</p>
|
<p>You can always add more users later.</p>
|
||||||
|
|
||||||
<p class="mt-10"><strong>Note that you cannot use your normal SSO Tools account to authenticate against your IdP.</strong> You can safely use dummy information for your users, since we won't be emailing them!</p>
|
<p><strong>Note that you cannot use your normal SSO Tools account to authenticate against your IdP.</strong> You can safely use dummy information for your users, since we won't be emailing them!</p>
|
||||||
|
|
||||||
|
<v-layout wrap style="margin: 30px auto;">
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field autofocus v-model="newUser.firstName" label="First name" required placeholder="Jane"></v-text-field>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field v-model="newUser.lastName" label="Last name" required placeholder="Doe"></v-text-field>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field v-model="newUser.email" label="Email address" required placeholder="jane@example.com"></v-text-field>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field v-model="newUser.password" label="Account password" required type='password' placeholder="password"></v-text-field>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
|
<v-btn @click="skip">Skip this step</v-btn>
|
||||||
|
|
||||||
<div class="d-block d-sm-flex flex-wrap mt-10 mb-10">
|
|
||||||
<v-text-field class="mr-2" autofocus v-model="newUser.firstName" label="First name" required placeholder="Jane"></v-text-field>
|
|
||||||
<v-text-field class="mr-2" v-model="newUser.lastName" label="Last name" required placeholder="Doe"></v-text-field>
|
|
||||||
<v-text-field class="mr-2" v-model="newUser.email" label="Email address" required placeholder="jane@example.com"></v-text-field>
|
|
||||||
<v-text-field class="mr-2" v-model="newUser.password" label="Account password" required type='password' placeholder="password"></v-text-field>
|
|
||||||
</div>
|
|
||||||
<v-btn @click="skip" class="mr-2">Skip this step</v-btn>
|
|
||||||
<v-btn :loading="creating" color='primary' v-on:click="createUser">Next</v-btn>
|
<v-btn :loading="creating" color='primary' v-on:click="createUser">Next</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="page === 2" style="text-align:center;">
|
<div v-if="page === 2" style="text-align:center;">
|
||||||
<h4>Step 3</h4>
|
<h4>Step 3</h4>
|
||||||
<h1>Create an app</h1>
|
<h1>Connect an app</h1>
|
||||||
<p>If you already have an app you'd like to connect to SSO Tools, you can add it below.</p>
|
<p>If you know the SAML2 settings for a service provider, you can them below to connect it to this IdP.</p>
|
||||||
<p>You can find and modify its SSO settings later.</p>
|
<p>You can find this IdP's own SAML settings after this setup. You can always add more apps later too.</p>
|
||||||
|
|
||||||
|
<v-layout wrap style="margin: 30px auto;">
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field autofocus label="Friendly name" required autofocus v-model="newSP.name" hint="To help you identify this SP." placeholder="My Service"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Service URL" v-model="newSP.serviceUrl" hint="The URL used to access your service. For example, for a webapp, you can just use your website URL." placeholder="https://sp.example.com"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="EntityID" v-model="newSP.entityId" hint="This is a URL to uniquely identify your service. It is sometimes the same as the metadata URL." placeholder="https://sp.example.com/metdadata"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="ACS URL" v-model="newSP.callbackUrl" hint="Assertion Consumer Service, or callback URL using the HTTP POST binding." placeholder="https://sp.example.com/callback"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Logout URL (optional)" v-model="newSP.logoutUrl" hint="The URL we will redirect IdP-initiated logout requests to." placeholder="https://sp.example.com/logout"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6>
|
||||||
|
<v-text-field label="Logout callback URL (optional)" v-model="newSP.logoutCallbackUrl" hint="The URL we will redirect users to after an SP-initiated logout." placeholder="https://sp.example.com/logout/callback"/>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
<v-btn @click="skip">Skip this step</v-btn>
|
||||||
|
|
||||||
<div class="d-block d-sm-flex flex-wrap mt-10 mb-10">
|
|
||||||
<v-text-field class="mr-2" label="Friendly name" required autofocus v-model="newSP.name" hint="To help you identify this SP." placeholder="My Service"/>
|
|
||||||
<v-text-field label="Service URL" v-model="newSP.serviceUrl" hint="Your app's URL" placeholder="https://myapp.com"/>
|
|
||||||
</div>
|
|
||||||
<v-btn @click="skip" class="mr-2">Skip this step</v-btn>
|
|
||||||
<v-btn :loading="creating" color='primary' v-on:click="createSP">Next</v-btn>
|
<v-btn :loading="creating" color='primary' v-on:click="createSP">Next</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="page === 3" class="w-100 mt-15 ml-auto mr-auto text-center">
|
<div v-if="page === 3" style="text-align:center;">
|
||||||
<h1>All done!</h1>
|
<h1>All done!</h1>
|
||||||
<p>Your new IdP is ready.</p>
|
<p>Your new IdP is ready.</p>
|
||||||
|
|
||||||
<h3 class="ma-10">What would you like to do now?</h3>
|
<h3 style="margin-top: 50px;">What would you like to do now?</h3>
|
||||||
|
|
||||||
<div class="mb-5"> <v-btn color='primary' :to="`/idps/${this._id}`">View IdP</v-btn></div>
|
<div style="margin-bottom:20px;"> <v-btn color='primary' :to="`/idps/${this._id}`">View IdP</v-btn></div>
|
||||||
|
<div><v-btn fluid :to="`/idps/${this._id}/saml`">View SAML2 setup</v-btn></div>
|
||||||
<div class="d-block d-sm-flex flex-wrap mt-10 justify-center">
|
<div><v-btn :to="`/idps/${this._id}/users`">Add more users</v-btn></div>
|
||||||
<v-btn class="ma-2" fluid :to="`/idps/${this._id}/saml`">View SAML2 setup</v-btn>
|
<div><v-btn :to="`/idps/${this._id}/sps`">Manage apps</v-btn></div>
|
||||||
<v-btn class="ma-2" :to="`/idps/${this._id}/users`">Add more users</v-btn>
|
|
||||||
<v-btn class="ma-2" :to="`/idps/${this._id}/sps`">Manage apps</v-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -141,7 +169,7 @@ export default {
|
|||||||
this.creating = false;
|
this.creating = false;
|
||||||
this.page = this.page + 1;
|
this.page = this.page + 1;
|
||||||
}, err => {
|
}, err => {
|
||||||
this.creating = false;
|
this.creating = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -153,7 +181,7 @@ export default {
|
|||||||
this.creating = false;
|
this.creating = false;
|
||||||
this.page = this.page + 1;
|
this.page = this.page + 1;
|
||||||
}, err => {
|
}, err => {
|
||||||
this.creating = false;
|
this.creating = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import { createApp } from 'vue'
|
import Vue from 'vue'
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import Vuetify from 'vuetify'
|
||||||
import { createStore } from 'vuex'
|
import VueRouter from 'vue-router';
|
||||||
import 'vuetify/styles'
|
import Vuex from 'vuex';
|
||||||
import { createVuetify } from 'vuetify'
|
|
||||||
import * as components from 'vuetify/components'
|
|
||||||
import * as directives from 'vuetify/directives'
|
|
||||||
import { aliases, mdi } from 'vuetify/iconsets/mdi'
|
|
||||||
import '@mdi/font/css/materialdesignicons.css'
|
|
||||||
|
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
import 'vuetify/dist/vuetify.min.css'
|
||||||
|
|
||||||
import Home from './components/Home.vue';
|
import Home from './components/Home.vue';
|
||||||
import ResetPassword from './components/ResetPassword.vue';
|
import ResetPassword from './components/ResetPassword.vue';
|
||||||
@ -26,7 +22,11 @@ import IDPLogs from './components/IdpLogs.vue';
|
|||||||
import PrivacyPolicy from './components/legal/PrivacyPolicy.vue';
|
import PrivacyPolicy from './components/legal/PrivacyPolicy.vue';
|
||||||
import TermsOfUse from './components/legal/TermsOfUse.vue';
|
import TermsOfUse from './components/legal/TermsOfUse.vue';
|
||||||
|
|
||||||
const store = createStore({
|
Vue.use(Vuetify);
|
||||||
|
Vue.use(VueRouter);
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
const store = new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
user: null,
|
user: null,
|
||||||
@ -59,13 +59,13 @@ const store = createStore({
|
|||||||
state.loginOpen = open;
|
state.loginOpen = open;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
const router = createRouter({
|
const router = new VueRouter({
|
||||||
scrollBehavior() {
|
scrollBehavior() {
|
||||||
return { left: 0, top: 0 };
|
return { x: 0, y: 0 };
|
||||||
},
|
},
|
||||||
history: createWebHistory(),
|
mode: 'history',
|
||||||
routes: [
|
routes: [
|
||||||
{ path: '/', component: Home },
|
{ path: '/', component: Home },
|
||||||
{ path: '/privacy', component: PrivacyPolicy },
|
{ path: '/privacy', component: PrivacyPolicy },
|
||||||
@ -75,7 +75,7 @@ const router = createRouter({
|
|||||||
{ path: '/dashboard', component: Dashboard },
|
{ path: '/dashboard', component: Dashboard },
|
||||||
{ path: '/idps/new', component: NewIDP },
|
{ path: '/idps/new', component: NewIDP },
|
||||||
{ path: '/idps/:id', component: IDP, children: [
|
{ path: '/idps/:id', component: IDP, children: [
|
||||||
{ path: '', component: IDPHome },
|
{ path: '/', component: IDPHome },
|
||||||
{ path: 'users', component: IDPUsers },
|
{ path: 'users', component: IDPUsers },
|
||||||
{ path: 'settings', component: IDPSettings },
|
{ path: 'settings', component: IDPSettings },
|
||||||
{ path: 'sps', component: IDPSPs },
|
{ path: 'sps', component: IDPSPs },
|
||||||
@ -85,20 +85,4 @@ const router = createRouter({
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const vuetify = createVuetify({
|
new Vue({ store, router, render: h => h(App) }).$mount('#app')
|
||||||
components,
|
|
||||||
directives,
|
|
||||||
icons: {
|
|
||||||
defaultSet: 'mdi',
|
|
||||||
aliases,
|
|
||||||
sets: {
|
|
||||||
mdi,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const app = createApp(App)
|
|
||||||
app.use(store)
|
|
||||||
app.use(vuetify)
|
|
||||||
app.use(router)
|
|
||||||
app.mount('#app')
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
plugins: [vue()]
|
|
||||||
}
|
|
11735
web/yarn.lock
11735
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user