This commit is contained in:
Jonathan Baecker 2020-01-29 17:40:15 +01:00
parent 928ebc7e3c
commit 5eed3bed89
23 changed files with 12089 additions and 0 deletions

View File

@ -0,0 +1,13 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View File

@ -0,0 +1,23 @@
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'@nuxtjs',
'plugin:nuxt/recommended'
],
// add your custom rules here
rules: {
'vue/html-indent': ['error', 4],
'vue/html-closing-bracket-newline': 'off',
'indent': [2, 4],
'no-tabs': 'off',
"no-console": 0,
"camelcase": ["error", {properties: "never"}]
}
}

90
ffplayout/frontend/.gitignore vendored Normal file
View File

@ -0,0 +1,90 @@
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
/logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# Nuxt generate
dist
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# IDE / Editor
.idea
# Service worker
sw.*
# Mac OSX
.DS_Store
# Vim swap files
*.swp

View File

@ -0,0 +1,22 @@
# ffplayout
> web GUI for ffplayout engine
## Build Setup
``` bash
# install dependencies
$ npm run install
# serve with hot reload at localhost:3000
$ npm run dev
# build for production and launch server
$ npm run build
$ npm run start
# generate static project
$ npm run generate
```
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).

View File

@ -0,0 +1,7 @@
# ASSETS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).

View File

@ -0,0 +1,497 @@
// Slate 4.3.1
// Bootswatch
// Variables ===================================================================
@mixin btn-shadow($color){
@include gradient-y-three-colors(lighten($color, 6%), $color, 60%, darken($color, 4%));
filter: none;
}
@mixin btn-shadow-inverse($color){
@include gradient-y-three-colors(darken($color, 18%), darken($color, 15%), 40%, darken($color, 13%));
filter: none;
}
// Navbar ======================================================================
.navbar {
border: 1px solid rgba(0, 0, 0, 0.6);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
.container {
padding: 0;
}
.navbar-toggler {
border-color: rgba(0, 0, 0, 0.6);
}
&-fixed-top {
border-width: 0 0 1px 0;
}
&-fixed-bottom {
border-width: 1px 0 0 0;
}
.nav-link {
padding: 1rem;
border-left: 1px solid rgba(255, 255, 255, 0.1);
border-right: 1px solid rgba(0, 0, 0, 0.2);
&:hover,
&:focus {
@include btn-shadow-inverse($gray-800);
border-left: 1px solid rgba(0, 0, 0, 0.2);
}
}
&-brand {
padding: 0.75rem 1rem calc(54px - 0.75rem - 30px);
margin-right: 0;
border-right: 1px solid rgba(0, 0, 0, 0.2);
}
.nav-item.active .nav-link {
background-color: rgba(0, 0, 0, 0.3);
border-left: 1px solid rgba(0, 0, 0, 0.2);
}
&-nav .nav-item + .nav-item {
margin-left: 0;
}
&.bg-light {
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
.nav-link {
&:hover,
&:focus {
@include btn-shadow-inverse($gray-600);
border-left: 1px solid rgba(0, 0, 0, 0.2);
}
}
}
}
@media (max-width: 576px) {
.navbar-expand-sm {
.navbar-brand,
.nav-link {
border: none !important;
}
}
}
@media (max-width: 768px) {
.navbar-expand-md {
.navbar-brand,
.nav-link {
border: none !important;
}
}
}
@media (max-width: 992px) {
.navbar-expand-lg {
.navbar-brand,
.nav-link {
border: none !important;
}
}
}
// Buttons =====================================================================
.btn {
border-color: rgba(0, 0, 0, 0.6);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
&:not([disabled]):not(.disabled).active,
&.disabled {
border-color: rgba(0, 0, 0, 0.6);
box-shadow: none;
}
&:hover,
&:focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled):active:hover,
&:not([disabled]):not(.disabled).active:hover {
border-color: rgba(0, 0, 0, 0.6);
}
}
.btn-primary {
@include btn-shadow($primary);
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active:hover,
&:not([disabled]):not(.disabled).active:hover {
@include btn-shadow-inverse($primary);
}
}
.btn-secondary {
@include btn-shadow($secondary);
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled).active {
@include btn-shadow-inverse($secondary);
}
}
.btn-success {
@include btn-shadow($success);
color: $white;
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled).active {
@include btn-shadow-inverse($success);
}
}
.btn-info {
@include btn-shadow($info);
color: $white;
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled).active {
@include btn-shadow-inverse($info);
}
}
.btn-warning {
@include btn-shadow($warning);
color: $white;
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled).active {
@include btn-shadow-inverse($warning);
}
}
.btn-danger {
@include btn-shadow($danger);
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled).active {
@include btn-shadow-inverse($danger);
}
}
.btn-link,
.btn-link:hover {
border-color: transparent;
}
.btn-group,
.btn-group-vertical {
.btn.active {
border-color: rgba(0, 0, 0, 0.6);
}
}
// Typography ==================================================================
h1, h2, h3, h4, h5, h6 {
text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.3);
}
// Tables ======================================================================
.table {
&-primary,
&-secondary,
&-success,
&-info,
&-warning,
&-danger {
color: #fff;
}
&-primary {
&, > th, > td {
background-color: $primary;
}
}
&-secondary {
&, > th, > td {
background-color: $secondary;
}
}
&-light {
&, > th, > td {
background-color: $light;
}
}
&-dark {
&, > th, > td {
background-color: $dark;
}
}
&-success {
&, > th, > td {
background-color: $success;
}
}
&-info {
&, > th, > td {
background-color: $info;
}
}
&-danger {
&, > th, > td {
background-color: $danger;
}
}
&-warning {
&, > th, > td {
background-color: $warning;
}
}
&-active {
&, > th, > td {
background-color: $table-active-bg;
}
}
&-hover {
.table-primary:hover {
&, > th, > td {
background-color: darken($primary, 5%);
}
}
.table-secondary:hover {
&, > th, > td {
background-color: darken($secondary, 5%);
}
}
.table-light:hover {
&, > th, > td {
background-color: darken($light, 5%);
}
}
.table-dark:hover {
&, > th, > td {
background-color: darken($dark, 5%);
}
}
.table-success:hover {
&, > th, > td {
background-color: darken($success, 5%);
}
}
.table-info:hover {
&, > th, > td {
background-color: darken($info, 5%);
}
}
.table-danger:hover {
&, > th, > td {
background-color: darken($danger, 5%);
}
}
.table-warning:hover {
&, > th, > td {
background-color: darken($warning, 5%);
}
}
.table-active:hover {
&, > th, > td {
background-color: $table-active-bg;
}
}
}
}
// Forms =======================================================================
legend {
color: #fff;
}
.input-group-addon {
@include btn-shadow($secondary);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
color: $white;
}
// Navs ========================================================================
.nav-tabs {
.nav-link {
@include btn-shadow-inverse($gray-800);
border: 1px solid rgba(0, 0, 0, 0.6);
&:not([disabled]):not(.disabled):hover,
&:not([disabled]):not(.disabled):focus,
&:not([disabled]):not(.disabled):active,
&:not([disabled]):not(.disabled).active {
@include btn-shadow($gray-800);
}
&.disabled {
border: 1px solid rgba(0, 0, 0, 0.6);
}
}
.nav-link,
.nav-link:hover {
color: #fff;
}
}
.nav-pills {
.nav-link {
@include btn-shadow($gray-800);
border: 1px solid rgba(0, 0, 0, 0.6);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
color: #fff;
&:hover {
@include btn-shadow-inverse($gray-800);
border: 1px solid rgba(0, 0, 0, 0.6);
}
}
.nav-link.active,
.nav-link:hover {
background-color: transparent;
@include btn-shadow-inverse($gray-800);
border: 1px solid rgba(0, 0, 0, 0.6);
}
.nav-link.disabled,
.nav-link.disabled:hover {
@include btn-shadow($gray-800);
color: $nav-link-disabled-color;
}
}
.pagination {
.page-link {
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
@include btn-shadow($gray-800);
&:hover {
@include btn-shadow-inverse($gray-800);
text-decoration: none;
}
}
.page-item.active .page-link {
@include btn-shadow-inverse($gray-800);
}
.page-item.disabled .page-link {
@include btn-shadow($gray-800);
}
}
.breadcrumb {
border: 1px solid rgba(0, 0, 0, 0.6);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
background-color: transparent;
@include btn-shadow($gray-800);
a,
a:hover {
color: #fff;
}
}
// Indicators ==================================================================
.alert {
.close {
color: $close-color;
text-decoration: none;
}
}
.alert {
border: none;
color: $white;
a,
.alert-link {
color: #fff;
text-decoration: underline;
}
@each $color, $value in $theme-colors {
&-#{$color} {
background-color: $value;
}
}
&-light {
&,
& a:not(.btn),
& .alert-link {
color: $body-bg;
}
}
}
.badge {
&-success,
&-warning,
&-info {
color: $white;
}
}
// Progress bars ===============================================================
// Containers ==================================================================
.jumbotron {
border: 1px solid rgba(0, 0, 0, 0.6);
}
.list-group {
&-item:hover {
background-color: darken($gray-900, 5%);
}
}

View File

@ -0,0 +1,164 @@
// Slate 4.3.1
// Bootswatch
//
// Color system
//
$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #e9ecef !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #999 !default;
$gray-600: #7A8288 !default;
$gray-700: #52575C !default;
$gray-800: #3A3F44 !default;
$gray-900: #272B30 !default;
$black: #000 !default;
$blue: #007bff !default;
$indigo: #6610f2 !default;
$purple: #6f42c1 !default;
$pink: #e83e8c !default;
$red: #ee5f5b !default;
$orange: #fd7e14 !default;
$yellow: #f89406 !default;
$green: #62c462 !default;
$teal: #20c997 !default;
$cyan: #5bc0de !default;
$primary: $gray-800 !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-200 !default;
$dark: $gray-900 !default;
$yiq-contrasted-threshold: 170 !default;
// Body
$body-bg: $gray-900 !default;
$body-color: #aaa !default;
// Links
$link-color: $white !default;
// Fonts
$font-size-base: 0.9375rem !default;
// Tables
$table-color: $white !default;
$table-accent-bg: rgba($white,.05) !default;
$table-hover-bg: rgba($white,.075) !default;
$table-border-color: rgba($black,.6) !default;
$table-dark-border-color: $table-border-color !default;
$table-dark-color: $white !default;
// Buttons
$input-btn-padding-y: .75rem !default;
$input-btn-padding-x: 1rem !default;
// Forms
$input-disabled-bg: #ccc !default;
// Dropdowns
$dropdown-bg: $gray-800 !default;
$dropdown-border-color: rgba($black, .6) !default;
$dropdown-divider-bg: rgba($black,.15) !default;
$dropdown-link-color: $body-color !default;
$dropdown-link-hover-color: $white !default;
$dropdown-link-hover-bg: $body-bg !default;
// Navs
$nav-tabs-border-color: rgba($black, 0.6) !default;
$nav-tabs-link-hover-border-color: $nav-tabs-border-color !default;
$nav-tabs-link-active-color: $white !default;
$nav-tabs-link-active-border-color: $nav-tabs-border-color !default;
// Navbar
$navbar-padding-y: 0 !default;
$navbar-dark-hover-color: $white !default;
$navbar-light-hover-color: $gray-800 !default;
$navbar-light-active-color: $gray-800 !default;
// Pagination
$pagination-color: $white !default;
$pagination-bg: transparent !default;
$pagination-border-color: rgba($black, 0.6) !default;
$pagination-hover-color: $white !default;
$pagination-hover-bg: transparent !default;
$pagination-hover-border-color: rgba($black, 0.6) !default;
$pagination-active-bg: transparent !default;
$pagination-active-border-color: rgba($black, 0.6) !default;
$pagination-disabled-bg: transparent !default;
$pagination-disabled-border-color: rgba($black, 0.6) !default;
// Jumbotron
$jumbotron-bg: darken($gray-900, 5%) !default;
// Cards
$card-border-color: rgba($black, 0.6) !default;
$card-cap-bg: lighten($gray-800, 10%) !default;
$card-bg: lighten($body-bg, 5%) !default;
// Popovers
$popover-bg: lighten($body-bg, 5%) !default;
// Modals
$modal-content-bg: lighten($body-bg, 5%) !default;
$modal-header-border-color: rgba(0,0,0,.2) !default;
// Progress bars
$progress-bg: darken($gray-900, 5%) !default;
$progress-bar-color: $gray-600 !default;
// List group
$list-group-bg: lighten($body-bg, 5%) !default;
$list-group-border-color: rgba($black, 0.6) !default;
$list-group-hover-bg: lighten($body-bg, 10%) !default;
$list-group-active-color: $white !default;
$list-group-active-bg: $list-group-hover-bg !default;
$list-group-active-border-color: $list-group-border-color !default;
$list-group-disabled-color: $gray-700 !default;
$list-group-action-color: $white !default;
// Breadcrumbs
$breadcrumb-active-color: $gray-500 !default;
// Code
$pre-color: inherit !default;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
# COMPONENTS
**This directory is not required, you can delete it if you don't want to use it.**
The components directory contains your Vue.js Components.
_Nuxt.js doesn't supercharge these components._

View File

@ -0,0 +1,7 @@
# LAYOUTS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Application Layouts.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).

View File

@ -0,0 +1,22 @@
<template>
<div>
<nuxt />
</div>
</template>
<style>
html, body {
font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial, sans-serif;
font-size: 16px;
word-spacing: 1px;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
height: 100%;
padding: 0;
margin: 0;
}
</style>

View File

@ -0,0 +1,8 @@
# MIDDLEWARE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your application middleware.
Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).

View File

@ -0,0 +1,83 @@
require('dotenv').config()
export default {
mode: 'spa',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || '',
meta: [{
charset: 'utf-8'
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1'
},
{
hid: 'description',
name: 'description',
content: process.env.npm_package_description || ''
}
],
link: [{
rel: 'icon',
type: 'image/x-icon',
href: '/favicon.ico'
}]
},
/*
** Customize the progress-bar color
*/
loading: {
color: '#ff9c36'
},
/*
** Global CSS
*/
css: [
'@/assets/css/bootstrap.min.css'
],
/*
** Plugins to load before mounting the App
*/
plugins: [],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'@nuxtjs/eslint-module'
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://bootstrap-vue.js.org
'bootstrap-vue/nuxt',
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios',
// Doc: https://github.com/nuxt-community/dotenv-module
'@nuxtjs/dotenv'
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
baseURL: process.env.API_URL
},
bootstrapVue: {
bootstrapCSS: false,
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {}
}
}

10885
ffplayout/frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
{
"name": "ffplayout",
"version": "2.0.0",
"description": "web GUI for ffplayout engine",
"author": "Jonathan Baecker",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
},
"dependencies": {
"@nuxtjs/axios": "^5.3.6",
"@nuxtjs/dotenv": "^1.4.0",
"bootstrap": "^4.1.3",
"bootstrap-vue": "^2.0.0",
"jwt-decode": "^2.2.0",
"nuxt": "^2.0.0"
},
"devDependencies": {
"@nuxtjs/eslint-config": "^1.0.1",
"@nuxtjs/eslint-module": "^1.0.0",
"babel-eslint": "^10.0.1",
"eslint": "^6.1.0",
"eslint-plugin-nuxt": ">=0.4.2"
}
}

View File

@ -0,0 +1,6 @@
# PAGES
This directory contains your Application Views and Routes.
The framework reads all the `*.vue` files inside this directory and creates the router of your application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).

View File

@ -0,0 +1,100 @@
<template>
<b-container class="login-container">
<div>
<div class="header">
<h1>ffplayout</h1>
</div>
<div v-if="!$store.state.auth.isLogin">
<b-form @submit.prevent="login" class="login-form">
<p v-if="formError" class="error">
{{ formError }}
</p>
<b-form-group id="input-group-1" label="User:" label-for="input-user">
<b-form-input id="input-user" v-model="formUsername" type="text" required placeholder="Username" />
</b-form-group>
<b-form-group id="input-group-1" label="Password:" label-for="input-pass">
<b-form-input id="input-pass" v-model="formPassword" type="password" required placeholder="Password" />
</b-form-group>
<b-button type="submit" variant="primary">
Login
</b-button>
</b-form>
</div>
<div v-else>
<br>
<br>
<h3>Wellcome to ffplayout manager!</h3>
</div>
</div>
</b-container>
</template>
<script>
export default {
components: {},
data () {
return {
formError: null,
formUsername: '',
formPassword: ''
}
},
created () {
this.init()
},
methods: {
async init () {
await this.$store.dispatch('auth/inspectToken')
this.checkLogin()
},
async login () {
try {
await this.$store.dispatch('auth/obtainToken', {
username: this.formUsername,
password: this.formPassword
})
this.formUsername = ''
this.formPassword = ''
this.formError = null
this.checkLogin()
} catch (e) {
this.formError = e.message
}
},
async logout () {
try {
await this.$store.commit('auth/REMOVE_TOKEN')
await this.$store.commit('auth/UPDATE_IS_LOGIN', false)
} catch (e) {
this.formError = e.message
}
},
checkLogin () {
if (this.$store.state.auth.isLogin) {
// this.$router.push('/player')
}
}
}
}
</script>
<style>
.login-container {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.header {
text-align: center;
margin-bottom: 3em;
}
.login-form {
min-width: 300px;
}
</style>

View File

@ -0,0 +1,7 @@
# PLUGINS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).

View File

@ -0,0 +1,11 @@
# STATIC
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your static files.
Each file inside this directory is mapped to `/`.
Thus you'd want to delete this README.md before deploying to production.
Example: `/static/robots.txt` is mapped as `/robots.txt`.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,10 @@
# STORE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Vuex Store files.
Vuex Store option is implemented in the Nuxt.js framework.
Creating a file in this directory automatically activates the option in the framework.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).

View File

@ -0,0 +1,85 @@
/* eslint-disable camelcase */
import jwt_decode from 'jwt-decode'
export const state = () => ({
jwtToken: localStorage.getItem('token'),
jwtRefresh: localStorage.getItem('refresh'),
isLogin: false
})
// mutate values in state
export const mutations = {
UPADTE_TOKEN (state, obj) {
localStorage.setItem('token', obj.token)
state.jwtToken = obj.token
if (obj.refresh) {
localStorage.setItem('refresh', obj.refresh)
state.jwtRefresh = obj.refresh
}
},
REMOVE_TOKEN (state) {
localStorage.removeItem('token')
localStorage.removeItem('refresh')
state.jwtToken = null
state.jwtRefresh = null
},
UPDATE_IS_LOGIN (state, bool) {
state.isLogin = bool
}
}
export const actions = {
async obtainToken ({ commit, state }, { username, password }) {
const payload = {
username,
password
}
await this.$axios.post('auth/token/', payload)
.then((response) => {
console.log('obtainToken: ', response)
commit('UPADTE_TOKEN', { token: response.data.access, refresh: response.data.refresh })
commit('UPDATE_IS_LOGIN', true)
})
.catch((error) => {
console.log(error)
})
},
async refreshToken ({ commit, state }) {
const payload = {
refresh: state.jwtRefresh
}
const response = await this.$axios.post('auth/token/refresh/', payload)
console.log('refreshToken: ', response)
commit('UPADTE_TOKEN', { token: response.data.access })
commit('UPDATE_IS_LOGIN', true)
},
async inspectToken ({ commit, dispatch, state }) {
const token = state.jwtToken
const refresh = state.jwtRefresh
if (token && refresh) {
const decoded_token = jwt_decode(token)
const decoded_refresh = jwt_decode(refresh)
const timestamp = Date.now() / 1000
const expire_token = decoded_token.exp
const expire_refresh = decoded_refresh.exp
if (expire_token - timestamp > 0) {
// DO NOTHING, DO NOT REFRESH
commit('UPDATE_IS_LOGIN', true)
console.log('token is valid, for: ' + Math.floor(expire_token - timestamp) + ' seconds')
} else if (expire_refresh - timestamp > 0) {
await dispatch('refreshToken')
console.log('update token')
} else {
// PROMPT USER TO RE-LOGIN, THIS ELSE CLAUSE COVERS THE CONDITION WHERE A TOKEN IS EXPIRED AS WELL
commit('UPDATE_IS_LOGIN', false)
console.log('new login')
}
} else {
commit('UPDATE_IS_LOGIN', false)
console.log('new login')
}
}
}

View File

@ -0,0 +1 @@
export const strict = false