Merge branch 'dev'

This commit is contained in:
Bubka 2022-05-14 13:57:04 +02:00
commit fb536aca98
20 changed files with 166 additions and 61 deletions

View File

@ -1,4 +1,4 @@
name: CI
name: ci-docker-latest
on:
push:
branches:
@ -86,33 +86,23 @@ jobs:
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set variables
id: vars
id: set_vars
env:
EVENT_NAME: ${{ github.event_name }}
run: |
BRANCH=${GITHUB_REF#refs/heads/}
TAG=${GITHUB_REF#refs/tags/}
echo ::set-output name=commit::$(git rev-parse --short HEAD)
echo ::set-output name=created::$(date -u +%Y-%m-%dT%H:%M:%SZ)
if [ "$TAG" != "$GITHUB_REF" ]; then
echo ::set-output name=version::$TAG
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7
elif [ "$BRANCH" = "master" ]; then
echo ::set-output name=version::latest
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7
else
echo ::set-output name=version::$BRANCH
echo ::set-output name=platforms::linux/amd64
fi
echo ::set-output name=version::latest
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7
- name: Build and push final image
- name: Build and push to docker Hub
uses: docker/build-push-action@v2.6.1
with:
platforms: ${{ steps.vars.outputs.platforms }}
platforms: ${{ steps.set_vars.outputs.platforms }}
build-args: |
CREATED=${{ steps.vars.outputs.created }}
COMMIT=${{ steps.vars.outputs.commit }}
VERSION=${{ steps.vars.outputs.version }}
CREATED=${{ steps.set_vars.outputs.created }}
COMMIT=${{ steps.set_vars.outputs.commit }}
VERSION=${{ steps.set_vars.outputs.version }}
tags: |
2fauth/2fauth:${{ steps.vars.outputs.version }}
2fauth/2fauth:${{ steps.set_vars.outputs.version }}
push: true

59
.github/workflows/ci-docker-release.yml vendored Normal file
View File

@ -0,0 +1,59 @@
name: ci-docker-release
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
with:
ref: ${{ github.event.release.tag_name }}
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
username: 2fauth
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set version
uses: actions/github-script@v4
id: set_version
with:
script: |
const tag = context.ref.substring(10)
const version = tag.replace('v', '')
core.setOutput('version', version)
- name: Set variables
id: set_vars
env:
EVENT_NAME: ${{ github.event_name }}
run: |
echo ::set-output name=commit::$(git rev-parse --short HEAD)
echo ::set-output name=created::$(date -u +%Y-%m-%dT%H:%M:%SZ)
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7
- name: Update Docker Hub Description
uses: peter-evans/dockerhub-description@v2.4.3
with:
username: 2fauth
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: 2fauth/2fauth
short-description: A web app to manage your Two-Factor Authentication (2FA) accounts and generate their security codes
readme-filepath: docker/README.md
- name: Build and push to docker Hub
uses: docker/build-push-action@v2.6.1
with:
platforms: ${{ steps.set_vars.outputs.platforms }}
build-args: |
CREATED=${{ steps.set_vars.outputs.created }}
COMMIT=${{ steps.set_vars.outputs.commit }}
VERSION=${{ steps.set_version.outputs.version }}
tags: |
2fauth/2fauth:${{ steps.set_version.outputs.version }}
push: true

View File

@ -1,24 +0,0 @@
name: Docker Hub description
on:
push:
branches: [master]
paths:
- docker/README.md
- .github/workflows/dockerhub-readme.yml
jobs:
dockerHubDescription:
if: |
(github.event_name == 'push' && github.repository == 'Bubka/2fauth') ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'Bubka/2fauth' && github.actor != 'dependabot[bot]')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2.3.4
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v2.4.3
with:
username: 2fauth
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: 2fauth/2fauth
short-description: A web app to manage your Two-Factor Authentication (2FA) accounts and generate their security codes
readme-filepath: docker/README.md

View File

@ -44,7 +44,7 @@ class Kernel extends HttpKernel
'behind-auth' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\Authenticate::class,

View File

@ -46,7 +46,7 @@ public function handle($request, Closure $next, ...$quards)
Auth::logout();
}
return response()->json(['message' => 'unauthorised'], Response::HTTP_UNAUTHORIZED);
return response()->json(['message' => 'inactivity detected'], Response::HTTP_I_AM_A_TEAPOT);
}
return $next($request);

View File

@ -1,5 +1,25 @@
# Change log
## [3.0.2] - 2022-05-11
### Added
- Mail settings section in the docker readme by [@aronmal](https://github.com/aronmal)
### Fixed
- [issue #72](https://github.com/Bubka/2FAuth/issues/72) 2FA secret passed as plain text rejected by form validation
- [issue #73](https://github.com/Bubka/2FAuth/issues/73) CSRF token mismatch
- [issue #78](https://github.com/Bubka/2FAuth/issues/78) Add tags other then latest when pushing images to dockerhub
## [3.0.1] - 2022-05-11
### Fixed
- [issue #68](https://github.com/Bubka/2FAuth/issues/68) 2fauth not run after update
- [issue #71](https://github.com/Bubka/2FAuth/issues/71) Cannot view old TOTP entries on latest Docker Image
- Missing login information on the demo website
## [3.0.0] - 2022-05-09
Finally, here is version 3.0!

View File

@ -9,7 +9,7 @@
|
*/
'version' => '3.0.0',
'version' => '3.0.2',
/*
|--------------------------------------------------------------------------

View File

@ -37,6 +37,7 @@ ## Setup
```sh
docker run -it --rm -p 8000:8000/tcp \
-v /yourpath/2fauth:/2fauth 2fauth/2fauth
-e AUTHENTICATION_GUARD=web-guard #fix for issue #68
```
1. Access it at [http://localhost:8000](http://localhost:8000)
@ -44,7 +45,7 @@ ## Setup
You can stop it with `CTRL+C`.
- You can also run it in the background by replacing `-it --rm` with `-d`.
- You can set environment variables available (see the [.env.example](https://github.com/Bubka/2FAuth/blob/master/.env.example)) with `-e`, for example `-e APP_NAME=2FAuth`.
- You can set environment variables available (see the [.env.example](../.env.example)) with `-e`, for example `-e APP_NAME=2FAuth`.
- You can also use the [docker-compose.yml](docker-compose.yml) with `docker-compose` and modify it as you wish.
### Use an existing SQLite file
@ -108,6 +109,27 @@ ### Build the image with build arguments
| `CREATED` | `an unknown date` | The date of the image build time |
| `COMMIT` | `unknown` | The commit hash of the Git commit used |
### Mail settings ####
| Build argument | Default | Description |
| --- | --- | --- |
| MAIL_HOST | smtp.mailtrap.io | The SMTP hostname |
| MAIL_PORT | 2525 | The coresponding SMTP port |
| MAIL_FROM | changeme@example.com | The sender adress |
| MAIL_USERNAME | null | The SMTP username |
| MAIL_PASSWORD | null | The SMTP password |
Example:
```
...
-e MAIL_HOST=smtp.example.com
-e MAIL_PORT=587
-e MAIL_FROM=2fauth@example.com
-e MAIL_USERNAME=2fauth@example.com
-e MAIL_PASSWORD=password1234
```
## Implementation details
- The final Docker image is based on `alpine:3.14` with minimal packages installed

13
package-lock.json generated
View File

@ -4,7 +4,6 @@
"requires": true,
"packages": {
"": {
"name": "2FAuth",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-brands-svg-icons": "^5.15.4",
@ -16,6 +15,7 @@
"bulma-checkradio": "^2.1.2",
"bulma-switch": "^2.0.0",
"object-equals": "^0.3.0",
"thirty-two": "github:osztenkurden/thirty-two#master",
"v-clipboard": "^2.2.3",
"vue": "^2.6.14",
"vue-axios": "^3.4.0",
@ -8981,6 +8981,13 @@
"node": ">= 8"
}
},
"node_modules/thirty-two": {
"version": "1.0.3",
"resolved": "git+ssh://git@github.com/osztenkurden/thirty-two.git#84e1dd6180a2d881565b5068630536a4414ecda9",
"engines": {
"node": ">=0.2.6"
}
},
"node_modules/thunky": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
@ -16695,6 +16702,10 @@
}
}
},
"thirty-two": {
"version": "git+ssh://git@github.com/osztenkurden/thirty-two.git#84e1dd6180a2d881565b5068630536a4414ecda9",
"from": "thirty-two@github:osztenkurden/thirty-two#master"
},
"thunky": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",

View File

@ -32,6 +32,7 @@
"bulma-checkradio": "^2.1.2",
"bulma-switch": "^2.0.0",
"object-equals": "^0.3.0",
"thirty-two": "github:osztenkurden/thirty-two#master",
"v-clipboard": "^2.2.3",
"vue": "^2.6.14",
"vue-axios": "^3.4.0",

2
public/js/app.js vendored

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,13 @@
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <http://feross.org>
* @license MIT
*/
/*!
* vue2-storage v6.1.3
* (c) 2021 Yarkov Aleksey
@ -24,6 +31,8 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
/**!
* Sortable 1.10.2
* @author RubaXa <trash@rubaxa.org>

2
public/js/vendor.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"/js/app.js": "/js/app.js?id=d61807e6be0ecfc97e48",
"/js/app.js": "/js/app.js?id=7b4a36a5b48772331b88",
"/js/manifest.js": "/js/manifest.js?id=4389b451d031e5974311",
"/css/app.css": "/css/app.css?id=9e9c2d6e9d06d9e51aa5",
"/js/vendor.js": "/js/vendor.js?id=045a97d46605524aafe8"
"/js/vendor.js": "/js/vendor.js?id=9dbc5644629b712eb43c"
}

10
resources/js/api.js vendored
View File

@ -39,6 +39,16 @@ Vue.axios.interceptors.response.use(response => response, error => {
if ( error.response.status === 401 ) {
routeName = 'login'
}
// api calls are stateless so when user inactivity is detected
// by the backend middleware it cannot logout the user directly
// so it returns a 418 response.
// We catch the 418 response and push the user to the login view
// with the instruction to request a session logout
if ( error.response.status === 418 ) {
router.push({ name: 'login', params: { forceLogout: true } })
throw new Vue.axios.Cancel();
}
if ( error.response.status === 404 ) routeName = '404'

View File

@ -13,11 +13,8 @@ Vue.mixin({
async appLogout(evt) {
await this.axios.get('/user/logout')
this.$storage.clear()
delete this.axios.defaults.headers.common['Authorization']
this.$router.push({ name: 'login' })
location.reload()
},
exitSettings: function(event) {

View File

@ -130,6 +130,8 @@
beforeRouteEnter (to, from, next) {
next(async vm => {
if( to.params.forceLogout ) await vm.axios.get('/user/logout')
const { data } = await vm.axios.get('api/v1/user/name')
if( data.name ) {

View File

@ -87,7 +87,7 @@
<div class="field has-addons">
<p class="control">
<span class="select">
<select v-model="form.secretIsBase32Encoded">
<select @change="form.secret=''" v-model="form.secretIsBase32Encoded">
<option v-for="format in secretFormats" :value="format.value">{{ format.text }}</option>
</select>
</span>
@ -176,6 +176,7 @@
import Modal from '../../components/Modal'
import Form from './../../components/Form'
import OtpDisplayer from '../../components/OtpDisplayer'
import Base32 from "thirty-two"
export default {
data() {
@ -275,6 +276,9 @@
// set current temp icon as account icon
this.form.icon = this.tempIcon
// Secret to base32 if necessary
this.form.secret = this.form.secretIsBase32Encoded ? this.form.secret : Base32.encode(this.form.secret).toString();
await this.form.post('/api/v1/twofaccounts')
if( this.form.errors.any() === false ) {

View File

@ -33,7 +33,7 @@
<div class="field has-addons">
<p class="control">
<span class="select">
<select v-model="form.secretIsBase32Encoded">
<select @change="form.secret=''" v-model="form.secretIsBase32Encoded">
<option v-for="format in secretFormats" :value="format.value">{{ format.text }}</option>
</select>
</span>
@ -110,6 +110,7 @@
import Modal from '../../components/Modal'
import Form from './../../components/Form'
import OtpDisplayer from '../../components/OtpDisplayer'
import Base32 from "thirty-two"
export default {
data() {
@ -201,6 +202,9 @@
this.deleteIcon()
}
// Secret to base32 if necessary
this.form.secret = this.form.secretIsBase32Encoded ? this.form.secret : Base32.encode(this.form.secret).toString();
await this.form.put('/api/v1/twofaccounts/' + this.$route.params.twofaccountId)
if( this.form.errors.any() === false ) {

View File

@ -159,7 +159,7 @@ public function test_user_logout_returns_validation_success()
/**
* @test
*/
public function test_user_logout_after_inactivity_returns_unauthorized()
public function test_user_logout_after_inactivity_returns_teapot()
{
// Set the autolock period to 1 minute
$settingService = resolve('App\Services\SettingService');
@ -178,7 +178,7 @@ public function test_user_logout_after_inactivity_returns_unauthorized()
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/twofaccounts')
->assertUnauthorized();
->assertStatus(418);
}
}