mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-02-03 20:19:57 +01:00
Merge branch 'dev'
This commit is contained in:
commit
fb536aca98
@ -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
59
.github/workflows/ci-docker-release.yml
vendored
Normal 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
|
24
.github/workflows/dockerhub-readme.yml
vendored
24
.github/workflows/dockerhub-readme.yml
vendored
@ -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
|
@ -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,
|
||||
|
@ -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);
|
||||
|
20
changelog.md
20
changelog.md
@ -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!
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
|
||||
*/
|
||||
|
||||
'version' => '3.0.0',
|
||||
'version' => '3.0.2',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -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
13
package-lock.json
generated
@ -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",
|
||||
|
@ -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
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
@ -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
2
public/js/vendor.js
vendored
File diff suppressed because one or more lines are too long
@ -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
10
resources/js/api.js
vendored
@ -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'
|
||||
|
||||
|
5
resources/js/mixins.js
vendored
5
resources/js/mixins.js
vendored
@ -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) {
|
||||
|
@ -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 ) {
|
||||
|
@ -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 ) {
|
||||
|
@ -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 ) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user