Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(frontend): authorization frontend #404

Merged
merged 28 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5810fa9
signin button in presenter redirects to signin page in frontend
Mogge Mar 27, 2024
cca1091
simple signin page
Mogge Mar 27, 2024
675845c
switch ports between frontend (now 3000) and presenter (now 3001)
Mogge Mar 27, 2024
726a4ef
copy auth page from presenter
Mogge Mar 27, 2024
10f458c
copy silent refresh page from presenter
Mogge Mar 27, 2024
d7a671e
looks like everything is working ...
Mogge Mar 27, 2024
8cdb089
fix port
Mogge Mar 27, 2024
b71c2fc
remove app page
Mogge Mar 27, 2024
920c6d4
do not call signin method when user already in store
Mogge Mar 27, 2024
d06eed8
clean up meta
Mogge Mar 27, 2024
f39ff5f
add page title to sign in
Mogge Mar 27, 2024
1ea3c0c
test global guard
Mogge Mar 27, 2024
60c8655
typesave test
Mogge Mar 27, 2024
8284866
test signin and auth guard
Mogge Mar 27, 2024
149e0be
purge tp menu, add sign out
Mogge Mar 27, 2024
204ea8e
purge index page
Mogge Mar 27, 2024
db09c40
remove about page
Mogge Mar 27, 2024
bef7350
clean up locales
Mogge Mar 27, 2024
cb9ef79
update authentik db, new policy
Mogge Mar 27, 2024
33969ae
Merge branch 'master' into authorization-frontend
Mogge Mar 27, 2024
560bdab
Update frontend/src/locales/de.json
Mogge Mar 28, 2024
8fdb6fc
fix env defaults for signin and signup
ulfgebhardt Mar 28, 2024
e49a551
conditional rendering of signout button
ulfgebhardt Mar 28, 2024
a1f5468
use authe store with pinia as arg
Mogge Mar 28, 2024
b15aa5e
Merge branch 'authorization-frontend' of github.com:dreammall-earth/d…
Mogge Mar 28, 2024
0be9ab8
fix unit tests after conditional sign out button
Mogge Mar 28, 2024
214015c
Merge branch 'master' into authorization-frontend
Mogge Apr 3, 2024
fd41310
disable cache
Mogge Apr 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified authentik/database.7z
Binary file not shown.
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ services:
- external-net
- internal-net
ports:
- 3000:3000
- 3001:3000
environment:
- NODE_ENV=production

Expand All @@ -50,7 +50,7 @@ services:
- external-net
- internal-net
ports:
- 3001:3000
- 3000:3000
environment:
- NODE_ENV=production

Expand Down
11 changes: 4 additions & 7 deletions frontend/.env.dist
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
# AUTH
# PUBLIC_ENV__AUTH__AUTHORITY and PUBLIC_ENV__AUTH__AUTHORITY_SIGNUP_URI
# are not default values since the default is to hide the signin/signup buttons
PUBLIC_ENV__AUTH__AUTHORITY="http://localhost:9000/application/o/dreammallearth/"
PUBLIC_ENV__AUTH__AUTHORITY_SIGNUP_URI="http://localhost:9000/if/flow/dreammallearth-enrollment/"
PUBLIC_ENV__AUTH__AUTHORITY_SIGNOUT_URI="http://localhost:9000/if/flow/dreammallearth-invalidation-flow/"
PUBLIC_ENV__AUTH__CLIENT_ID="G3g0sjCjph1NAyGeeu5Te5ltx1I7WZ0DGB8i6vOI"
PUBLIC_ENV__AUTH__REDIRECT_URI="http://localhost:3001/auth"
PUBLIC_ENV__AUTH__SILENT_REDIRECT_URI="http://localhost:3001/silent-refresh"
PUBLIC_ENV__AUTH__REDIRECT_URI="http://localhost:3000/auth"
PUBLIC_ENV__AUTH__SILENT_REDIRECT_URI="http://localhost:3000/silent-refresh"
PUBLIC_ENV__AUTH__RESPONSE_TYPE="code"
PUBLIC_ENV__AUTH__SCOPE="openid profile posts"
PUBLIC_ENV__AUTH__UNAUTHORIZED_REDIRECT_URI="http://localhost:3001/"

# Endpoints
PUBLIC_ENV__ENDPOINTS__GRAPHQL_URI=http://localhost:4000/

# META
PUBLIC_ENV__META__BASE_URL="http://localhost:3000"
PUBLIC_ENV__META__DEFAULT_AUTHOR="IT Team 4 Change"
PUBLIC_ENV__META__DEFAULT_DESCRIPTION="IT4C Frontend Boilerplate"
PUBLIC_ENV__META__DEFAULT_TITLE="IT4C"
PUBLIC_ENV__META__DEFAULT_AUTHOR="DreamMall Verlag GbR"
7 changes: 4 additions & 3 deletions frontend/renderer/utils.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { PageContext } from 'vike/types'

import { META } from '#src/env'
import i18n from '#plugins/i18n'

function getTitle(pageContext: PageContext) {
// The value exported by /pages/**/+title.js is available at pageContext.config.title
const val = pageContext.config.title
if (typeof val === 'string') return val
if (typeof val === 'function') return String(val(pageContext))
return META.DEFAULT_TITLE
return i18n.global.t('meta.defaultTitle')
}

function getDescription(pageContext: PageContext) {
const val = pageContext.config.description
if (typeof val === 'string') return val
if (typeof val === 'function') return val(pageContext)
return META.DEFAULT_DESCRIPTION
return i18n.global.t('meta.defaultDescription')
}

export { getTitle, getDescription }
2 changes: 1 addition & 1 deletion frontend/scripts/tests/plugin.pinia.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createTestingPinia } from '@pinia/testing'
import { config } from '@vue/test-utils'

config.global.plugins.push(createTestingPinia())
config.global.plugins.push(createTestingPinia({ stubActions: false }))
223 changes: 1 addition & 222 deletions frontend/src/components/__snapshots__/PageShell.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,228 +27,7 @@ exports[`PageShell > renders 1`] = `
<div
class="v-col"
>
<div
class="v-avatar v-theme--light v-avatar--density-default v-avatar--variant-flat ma-2 pa-1"
style="background-color: #333; color: #fff; caret-color: #fff; width: 48px; height: 48px;"
>
<div
aria-label=""
class="v-responsive v-img v-img--booting"
>
<div
class="v-responsive__sizer"
/>


<transition-stub
appear="true"
css="true"
name="fade-transition"
persisted="false"
>
<img
alt=""
class="v-img__img v-img__img--cover"
src="/src/assets/it4c-logo2-clean-bg_alpha-128x128.png"
style="display: none;"
/>
</transition-stub>
<transition-stub
appear="false"
css="true"
name="fade-transition"
persisted="false"
>
<!---->
</transition-stub>
<!---->
<!---->
<!---->


<!---->
</div>

<!---->
<span
class="v-avatar__underlay"
/>

</div>
</div>
<div
class="v-col d-flex align-center justify-center grow"
>
<a
class="v-btn v-theme--light v-btn--density-default v-btn--size-default v-btn--variant-flat"
href="/"
>

<span
class="v-btn__overlay"
/>
<span
class="v-btn__underlay"
/>

<!---->
<span
class="v-btn__content"
data-no-activator=""
>



$t('menu.home')



</span>
<!---->
<!---->
</a>
<a
class="v-btn v-theme--light v-btn--density-default v-btn--size-default v-btn--variant-flat"
href="/app"
>

<span
class="v-btn__overlay"
/>
<span
class="v-btn__underlay"
/>

<!---->
<span
class="v-btn__content"
data-no-activator=""
>



$t('menu.app')



</span>
<!---->
<!---->
</a>
<a
class="v-btn v-theme--light v-btn--density-default v-btn--size-default v-btn--variant-flat"
href="/about"
>

<span
class="v-btn__overlay"
/>
<span
class="v-btn__underlay"
/>

<!---->
<span
class="v-btn__content"
data-no-activator=""
>



$t('menu.about')



</span>
<!---->
<!---->
</a>
</div>
<div
class="v-col"
>
<div
class="v-input v-input--horizontal v-input--center-affix v-input--density-default v-locale--is-ltr v-input--dirty v-switch d-flex justify-end mr-5"
>
<!---->
<div
class="v-input__control"
>

<div
class="v-selection-control v-selection-control--dirty v-selection-control--density-default"
>
<div
class="v-selection-control__wrapper text-success"
>

<div
class="v-switch__track bg-success"
>
<!---->
<!---->
</div>

<div
class="v-selection-control__input"
>


<input
aria-describedby="switch-4-messages"
aria-disabled="false"
id="switch-4"
type="checkbox"
value="true"
/>
<div
class="v-switch__thumb bg-success"
>
<transition-stub
appear="false"
css="true"
name="scale-transition"
persisted="false"
>
<!---->
</transition-stub>
</div>


</div>
</div>
<label
class="v-label v-label--clickable"
for="switch-4"
>
<!---->

$t('language.german')

</label>
</div>

</div>
<!---->
<div
class="v-input__details"
>
<transition-stub
appear="false"
aria-live="polite"
class="v-messages"
css="true"
id="switch-4-messages"
name="slide-y-transition"
persisted="false"
role="alert"
tag="div"
>
<!---->
</transition-stub>
<!---->
</div>
</div>
<!--v-if-->
</div>
</div>

Expand Down
76 changes: 71 additions & 5 deletions frontend/src/components/menu/TopMenu.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,84 @@
import { mount } from '@vue/test-utils'
import { describe, it, expect } from 'vitest'
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { h } from 'vue'
import { VApp } from 'vuetify/components'

import { useAuthStore } from '#stores/authStore'
import { authService } from '#tests/mock.authService'

import TopMenu from './TopMenu.vue'

describe('TopMenu', () => {
const wrapper = mount(VApp, {
slots: {
default: h(TopMenu),
},
const Wrapper = () => {
return mount(VApp, {
slots: {
default: h(TopMenu),
},
})
}

let wrapper: ReturnType<typeof Wrapper>

beforeEach(() => {
wrapper = Wrapper()
})

it('renders', () => {
expect(wrapper.element).toMatchSnapshot()
})

describe('signout button', () => {
const authStore = useAuthStore()

const authServiceSpy = vi.spyOn(authService, 'signOut')
const storeSpy = vi.spyOn(authStore, 'clear')

beforeEach(() => {
vi.clearAllMocks()
authStore.save({
access_token: 'access_token',
profile: {
aud: 'aud',
sub: 'sub',
exp: 1,
iat: 1,
iss: 'iss',
},
token_type: 'token_type',
session_state: null,
state: null,
expires_in: 0,
expired: false,
scopes: ['email'],
toStorageString: () => 'toStorageString',
})
})

describe('without error', () => {
beforeEach(async () => {
await wrapper.find('button').trigger('click')
})

it('calls auth service sign out', () => {
expect(authServiceSpy).toBeCalled()
})

it('clears the store', () => {
expect(storeSpy).toBeCalled()
})
})

describe('with error', () => {
const consoleSpy = vi.spyOn(console, 'log')

beforeEach(async () => {
authServiceSpy.mockRejectedValue('Error!')
await wrapper.find('button').trigger('click')
})

it('logs the error', () => {
expect(consoleSpy).toBeCalledWith('auth error', 'Error!')
})
})
})
})
Loading