mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
refactor(webapp): make login, registration, password-reset layout brandable (#8440)
* Make login, registration, password-reset layout brandable - Rename some variables related to this * Remove experimental code * add lodash types * fix build fix type --------- Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
This commit is contained in:
parent
d7d8a242cd
commit
48c7bd0033
@ -105,6 +105,7 @@
|
|||||||
"@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
|
"@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
|
||||||
"@faker-js/faker": "9.7.0",
|
"@faker-js/faker": "9.7.0",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
|
"@types/lodash": "^4.17.16",
|
||||||
"@types/node": "^22.15.2",
|
"@types/node": "^22.15.2",
|
||||||
"@types/uuid": "~9.0.1",
|
"@types/uuid": "~9.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||||
|
|||||||
@ -1,5 +1,2 @@
|
|||||||
// this file is duplicated in `backend/src/config/metadata` and `webapp/constants/metadata.js`
|
// this file is duplicated in `backend/src/config/registration.ts` and `webapp/constants/registration.js`
|
||||||
export default {
|
export default {}
|
||||||
NONCE_LENGTH: 5,
|
|
||||||
INVITE_CODE_LENGTH: 6,
|
|
||||||
}
|
|
||||||
|
|||||||
12
backend/src/constants/registrationBranded.ts
Normal file
12
backend/src/constants/registrationBranded.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// this file is duplicated in `backend/src/config/registrationBranded.ts` and `webapp/constants/registrationBranded.js`
|
||||||
|
import { merge } from 'lodash'
|
||||||
|
|
||||||
|
import registration from '@constants/registration'
|
||||||
|
|
||||||
|
const defaultRegistration = {
|
||||||
|
NONCE_LENGTH: 5,
|
||||||
|
INVITE_CODE_LENGTH: 6,
|
||||||
|
LAYOUT: 'no-header',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default merge(defaultRegistration, registration)
|
||||||
@ -87,8 +87,9 @@ export default async function scrape(url) {
|
|||||||
throw new ApolloError('Not found', 'NOT_FOUND')
|
throw new ApolloError('Not found', 'NOT_FOUND')
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
if (!output.type) {
|
||||||
type: 'link',
|
output.type = 'link'
|
||||||
...output,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return output
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import CONSTANTS_REGISTRATION from '@constants/registration'
|
import registrationConstants from '@constants/registrationBranded'
|
||||||
|
|
||||||
export default function generateInviteCode() {
|
export default function generateInviteCode() {
|
||||||
// 6 random numbers in [ 0, 35 ] are 36 possible numbers (10 [0-9] + 26 [A-Z])
|
// 6 random numbers in [ 0, 35 ] are 36 possible numbers (10 [0-9] + 26 [A-Z])
|
||||||
return Array.from(
|
return Array.from(
|
||||||
{ length: CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH },
|
{ length: registrationConstants.INVITE_CODE_LENGTH },
|
||||||
(n: number = Math.floor(Math.random() * 36)) => {
|
(n: number = Math.floor(Math.random() * 36)) => {
|
||||||
// n > 9: it is a letter (ASCII 65 is A) -> 10 + 55 = 65
|
// n > 9: it is a letter (ASCII 65 is A) -> 10 + 55 = 65
|
||||||
// else: it is a number (ASCII 48 is 0) -> 0 + 48 = 48
|
// else: it is a number (ASCII 48 is 0) -> 0 + 48 = 48
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import CONSTANTS_REGISTRATION from '@constants/registration'
|
import registrationConstants from '@constants/registrationBranded'
|
||||||
|
|
||||||
// TODO: why this is not used in resolver 'requestPasswordReset'?
|
// TODO: why this is not used in resolver 'requestPasswordReset'?
|
||||||
export default function generateNonce() {
|
export default function generateNonce() {
|
||||||
return Array.from(
|
return Array.from(
|
||||||
{ length: CONSTANTS_REGISTRATION.NONCE_LENGTH },
|
{ length: registrationConstants.NONCE_LENGTH },
|
||||||
(n: number = Math.floor(Math.random() * 10)) => {
|
(n: number = Math.floor(Math.random() * 10)) => {
|
||||||
return String.fromCharCode(n + 48)
|
return String.fromCharCode(n + 48)
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
import CONSTANTS_REGISTRATION from '@constants/registration'
|
import registrationConstants from '@constants/registrationBranded'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getDriver } from '@db/neo4j'
|
import { getDriver } from '@db/neo4j'
|
||||||
import createServer from '@src/server'
|
import createServer from '@src/server'
|
||||||
@ -116,7 +116,7 @@ describe('inviteCodes', () => {
|
|||||||
GenerateInviteCode: {
|
GenerateInviteCode: {
|
||||||
code: expect.stringMatching(
|
code: expect.stringMatching(
|
||||||
new RegExp(
|
new RegExp(
|
||||||
`^[0-9A-Z]{${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH},${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH}}$`,
|
`^[0-9A-Z]{${registrationConstants.INVITE_CODE_LENGTH},${registrationConstants.INVITE_CODE_LENGTH}}$`,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expiresAt: null,
|
expiresAt: null,
|
||||||
@ -142,7 +142,7 @@ describe('inviteCodes', () => {
|
|||||||
GenerateInviteCode: {
|
GenerateInviteCode: {
|
||||||
code: expect.stringMatching(
|
code: expect.stringMatching(
|
||||||
new RegExp(
|
new RegExp(
|
||||||
`^[0-9A-Z]{${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH},${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH}}$`,
|
`^[0-9A-Z]{${registrationConstants.INVITE_CODE_LENGTH},${registrationConstants.INVITE_CODE_LENGTH}}$`,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expiresAt: nextWeek.toISOString(),
|
expiresAt: nextWeek.toISOString(),
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
import CONSTANTS_REGISTRATION from '@constants/registration'
|
import registrationConstants from '@constants/registrationBranded'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
import { getNeode, getDriver } from '@db/neo4j'
|
||||||
import createServer from '@src/server'
|
import createServer from '@src/server'
|
||||||
@ -118,7 +118,7 @@ describe('passwordReset', () => {
|
|||||||
const resets = await getAllPasswordResets()
|
const resets = await getAllPasswordResets()
|
||||||
const [reset] = resets
|
const [reset] = resets
|
||||||
const { nonce } = reset.properties
|
const { nonce } = reset.properties
|
||||||
expect(nonce).toHaveLength(CONSTANTS_REGISTRATION.NONCE_LENGTH)
|
expect(nonce).toHaveLength(registrationConstants.NONCE_LENGTH)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
|
||||||
import CONSTANTS_REGISTRATION from '@constants/registration'
|
import registrationConstants from '@constants/registrationBranded'
|
||||||
|
|
||||||
import createPasswordReset from './helpers/createPasswordReset'
|
import createPasswordReset from './helpers/createPasswordReset'
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ export default {
|
|||||||
Mutation: {
|
Mutation: {
|
||||||
requestPasswordReset: async (_parent, { email }, { driver }) => {
|
requestPasswordReset: async (_parent, { email }, { driver }) => {
|
||||||
// TODO: why this is generated differntly from 'backend/src/schema/resolvers/helpers/generateNonce.js'?
|
// TODO: why this is generated differntly from 'backend/src/schema/resolvers/helpers/generateNonce.js'?
|
||||||
const nonce = uuid().substring(0, CONSTANTS_REGISTRATION.NONCE_LENGTH)
|
const nonce = uuid().substring(0, registrationConstants.NONCE_LENGTH)
|
||||||
return createPasswordReset({ driver, nonce, email })
|
return createPasswordReset({ driver, nonce, email })
|
||||||
},
|
},
|
||||||
resetPassword: async (_parent, { email, nonce, newPassword }, { driver }) => {
|
resetPassword: async (_parent, { email, nonce, newPassword }, { driver }) => {
|
||||||
|
|||||||
@ -2061,6 +2061,11 @@
|
|||||||
"@types/koa-compose" "*"
|
"@types/koa-compose" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/lodash@^4.17.16":
|
||||||
|
version "4.17.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.16.tgz#94ae78fab4a38d73086e962d0b65c30d816bfb0a"
|
||||||
|
integrity sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==
|
||||||
|
|
||||||
"@types/long@^4.0.0":
|
"@types/long@^4.0.0":
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import CONSTANTS_REGISTRATION from './../../constants/registration'
|
import registrationConstants from '~/constants/registration'
|
||||||
|
|
||||||
export const isValidInviteCodeQuery = gql`
|
export const isValidInviteCodeQuery = gql`
|
||||||
query ($code: ID!) {
|
query ($code: ID!) {
|
||||||
@ -43,11 +43,11 @@ export default {
|
|||||||
formSchema: {
|
formSchema: {
|
||||||
inviteCode: {
|
inviteCode: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
min: CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH,
|
min: registrationConstants.INVITE_CODE_LENGTH,
|
||||||
max: CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH,
|
max: registrationConstants.INVITE_CODE_LENGTH,
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t('components.registration.invite-code.form.validations.length', {
|
message: this.$t('components.registration.invite-code.form.validations.length', {
|
||||||
inviteCodeLength: CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH,
|
inviteCodeLength: registrationConstants.INVITE_CODE_LENGTH,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { isEmail } from 'validator'
|
import { isEmail } from 'validator'
|
||||||
import CONSTANTS_REGISTRATION from './../../constants/registration'
|
import registrationConstants from '~/constants/registration'
|
||||||
|
|
||||||
import EmailDisplayAndVerify from './EmailDisplayAndVerify'
|
import EmailDisplayAndVerify from './EmailDisplayAndVerify'
|
||||||
|
|
||||||
@ -54,11 +54,11 @@ export default {
|
|||||||
formSchema: {
|
formSchema: {
|
||||||
nonce: {
|
nonce: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
min: CONSTANTS_REGISTRATION.NONCE_LENGTH,
|
min: registrationConstants.NONCE_LENGTH,
|
||||||
max: CONSTANTS_REGISTRATION.NONCE_LENGTH,
|
max: registrationConstants.NONCE_LENGTH,
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t('components.registration.email-nonce.form.validations.length', {
|
message: this.$t('components.registration.email-nonce.form.validations.length', {
|
||||||
nonceLength: CONSTANTS_REGISTRATION.NONCE_LENGTH,
|
nonceLength: registrationConstants.NONCE_LENGTH,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
1
webapp/constants/login.js
Normal file
1
webapp/constants/login.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default {}
|
||||||
8
webapp/constants/loginBranded.js
Normal file
8
webapp/constants/loginBranded.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { merge } from 'lodash'
|
||||||
|
import login from '~/constants/login.js'
|
||||||
|
|
||||||
|
const defaultLogin = {
|
||||||
|
LAYOUT: 'no-header',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default merge(defaultLogin, login)
|
||||||
@ -1,5 +1,2 @@
|
|||||||
// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js`
|
// this file is duplicated in `backend/src/config/registration.ts` and `webapp/constants/registration.js`
|
||||||
export default {
|
export default {}
|
||||||
NONCE_LENGTH: 5,
|
|
||||||
INVITE_CODE_LENGTH: 6,
|
|
||||||
}
|
|
||||||
|
|||||||
12
webapp/constants/registrationBranded.js
Normal file
12
webapp/constants/registrationBranded.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// this file is duplicated in `backend/src/config/registrationBranded.ts` and `webapp/constants/registrationBranded.js`
|
||||||
|
import { merge } from 'lodash'
|
||||||
|
|
||||||
|
import registration from '~/constants/registration.js'
|
||||||
|
|
||||||
|
const defaultRegistration = {
|
||||||
|
NONCE_LENGTH: 5,
|
||||||
|
INVITE_CODE_LENGTH: 6,
|
||||||
|
LAYOUT: 'no-header',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default merge(defaultRegistration, registration)
|
||||||
@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="fade" appear>
|
<div class="login-page">
|
||||||
<login-form @success="handleSuccess" />
|
<transition name="fade" appear>
|
||||||
</transition>
|
<login-form @success="handleSuccess" />
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LoginForm from '~/components/LoginForm/LoginForm.vue'
|
import LoginForm from '~/components/LoginForm/LoginForm.vue'
|
||||||
|
import loginConstants from '~/constants/loginBranded.js'
|
||||||
import { VERSION } from '~/constants/terms-and-conditions-version.js'
|
import { VERSION } from '~/constants/terms-and-conditions-version.js'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
layout: 'no-header',
|
layout: loginConstants.LAYOUT,
|
||||||
components: {
|
components: {
|
||||||
LoginForm,
|
LoginForm,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import links from '~/constants/links.js'
|
import links from '~/constants/links.js'
|
||||||
import metadata from '~/constants/metadata.js'
|
import metadata from '~/constants/metadata.js'
|
||||||
|
import loginConstants from '~/constants/loginBranded.js'
|
||||||
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
||||||
import Logo from '~/components/Logo/Logo'
|
import Logo from '~/components/Logo/Logo'
|
||||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||||
@ -27,7 +28,7 @@ export default {
|
|||||||
Logo,
|
Logo,
|
||||||
PageParamsLink,
|
PageParamsLink,
|
||||||
},
|
},
|
||||||
layout: 'no-header',
|
layout: loginConstants.LAYOUT,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
metadata,
|
metadata,
|
||||||
|
|||||||
@ -313,7 +313,7 @@ describe('Registration', () => {
|
|||||||
|
|
||||||
it('renders', async () => {
|
it('renders', async () => {
|
||||||
wrapper = await Wrapper()
|
wrapper = await Wrapper()
|
||||||
expect(wrapper.classes('registration-slider')).toBe(true)
|
expect(wrapper.find('.registration-slider')).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
// The asyncTests must go last
|
// The asyncTests must go last
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<registration-slider
|
<div class="registration-page">
|
||||||
:registrationType="registrationType.method"
|
<registration-slider
|
||||||
:activePage="registrationType.activePage"
|
:registrationType="registrationType.method"
|
||||||
:overwriteSliderData="overwriteSliderData"
|
:activePage="registrationType.activePage"
|
||||||
/>
|
:overwriteSliderData="overwriteSliderData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import registrationConstants from '~/constants/registrationBranded.js'
|
||||||
import RegistrationSlider from '~/components/Registration/RegistrationSlider'
|
import RegistrationSlider from '~/components/Registration/RegistrationSlider'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
layout: 'no-header',
|
layout: registrationConstants.LAYOUT,
|
||||||
name: 'Registration',
|
name: 'Registration',
|
||||||
components: {
|
components: {
|
||||||
RegistrationSlider,
|
RegistrationSlider,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user