Skip to content

Commit

Permalink
fix(cms): fix cms login errors on mongodb and postgresql (#104)
Browse files Browse the repository at this point in the history
fix #98
  • Loading branch information
bahdcoder authored May 25, 2021
1 parent 046d457 commit 88ff195
Show file tree
Hide file tree
Showing 15 changed files with 234 additions and 48 deletions.
2 changes: 1 addition & 1 deletion examples/blog/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ tensei()
])
.plugins([
welcome(),
// cms().plugin(),
cms().plugin(),
auth().rolesAndPermissions().refreshTokens()
// .cookieSessions()
.plugin(),
Expand Down
Binary file modified examples/blog/tensei.sqlite
Binary file not shown.
4 changes: 2 additions & 2 deletions packages/cli/_templates/default/new/package.json.ejs.t
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ to: <%= h.changeCase.param(name) %>/package.json
"build": "yarn build:server && yarn build:client"
},
"devDependencies": {
"@tensei/common": "^0.8.1",
"@tensei/components": "^0.8.1",
"@tensei/common": "^0.8.3",
"@tensei/components": "^0.8.3",
"autoprefixer": "^10.2.4",
"cross-env": "^7.0.3",
"laravel-mix": "^6.0.5",
Expand Down
11 changes: 5 additions & 6 deletions packages/cms/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,9 @@ class CmsPlugin {
!token[this.resources.user.data.snakeCaseName].active ||
token.expires_at < new Date()
) {
return response
.status(401)
.redirect(
`/${this.config.path}/auth/login?error=Your login credentials are invalid. Please try again.`
)
return response.redirect(
`/${this.config.path}/auth/login?error=Your login credentials are invalid. Please try again.`
)
}

request.manager.assign(token, {
Expand Down Expand Up @@ -249,7 +247,8 @@ class CmsPlugin {
}

let createUserPayload: any = {
email: payload.email
email: payload.email,
active: true
}

let roles = payload.admin_roles
Expand Down
21 changes: 11 additions & 10 deletions packages/cms/plugin/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@ export const setupCms = async (
await em.find(PermissionResource.data.pascalCaseName, {})
).map((permission: any) => permission.id)

if (!superAdminRole) {
superAdminRole = em.create(RoleResource.data.pascalCaseName, {
name: 'Super Admin',
slug: 'super-admin',
description:
'Manage the access and level of responsibility of all users on this network.',
admin_permissions: allPermissions
})
}

if (superAdminRole) {
em.assign(superAdminRole, {
admin_permissions: allPermissions
})
}

await em.persistAndFlush(
superAdminRole ||
em.create(RoleResource.data.pascalCaseName, {
name: 'Super Admin',
slug: 'super-admin',
description:
'Manage the access and level of responsibility of all users on this network.',
admin_permissions: allPermissions
})
)
await em.persistAndFlush(superAdminRole)
}

const getPermissionsToInsert = async (
Expand Down
10 changes: 5 additions & 5 deletions packages/create-tensei-app/templates/default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"@tensei/auth": "^0.8.2",
"@tensei/cms": "^0.8.2",
"@tensei/core": "^0.8.2",
"@tensei/media": "^0.8.2",
"@tensei/graphql": "^0.8.2"
"@tensei/auth": "^0.8.3",
"@tensei/cms": "^0.8.3",
"@tensei/core": "^0.8.3",
"@tensei/media": "^0.8.3",
"@tensei/graphql": "^0.8.3"
},
"scripts": {
"dev": "nodemon index.js",
Expand Down
12 changes: 6 additions & 6 deletions packages/create-tensei-app/templates/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"@tensei/auth": "^0.8.2",
"@tensei/cms": "^0.8.2",
"@tensei/core": "^0.8.2",
"@tensei/media": "^0.8.2",
"@tensei/next": "^0.8.2",
"@tensei/rest": "^0.8.2"
"@tensei/auth": "^0.8.3",
"@tensei/cms": "^0.8.3",
"@tensei/core": "^0.8.3",
"@tensei/media": "^0.8.3",
"@tensei/next": "^0.8.3",
"@tensei/rest": "^0.8.3"
},
"scripts": {
"dev": "nodemon index.js",
Expand Down
12 changes: 6 additions & 6 deletions packages/create-tensei-app/templates/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"@tensei/auth": "^0.8.2",
"@tensei/cms": "^0.8.2",
"@tensei/core": "^0.8.2",
"@tensei/media": "^0.8.2",
"@tensei/nuxt": "^0.8.2",
"@tensei/rest": "^0.8.2"
"@tensei/auth": "^0.8.3",
"@tensei/cms": "^0.8.3",
"@tensei/core": "^0.8.3",
"@tensei/media": "^0.8.3",
"@tensei/nuxt": "^0.8.3",
"@tensei/rest": "^0.8.3"
},
"scripts": {
"dev": "nodemon index.js",
Expand Down
10 changes: 5 additions & 5 deletions packages/create-tensei-app/templates/rest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"@tensei/auth": "^0.8.2",
"@tensei/cms": "^0.8.2",
"@tensei/core": "^0.8.2",
"@tensei/media": "^0.8.2",
"@tensei/rest": "^0.8.2"
"@tensei/auth": "^0.8.3",
"@tensei/cms": "^0.8.3",
"@tensei/core": "^0.8.3",
"@tensei/media": "^0.8.3",
"@tensei/rest": "^0.8.3"
},
"scripts": {
"dev": "nodemon index.js",
Expand Down
5 changes: 5 additions & 0 deletions packages/tests/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export const sortArrayById = (items: any[]) =>

export let gql = (t: any) => t.toString()

export const getFakeMailer = () => ({
send: jest.fn(),
sendRaw: jest.fn()
})

export const setupFakeMailer = ({ sendRaw, send }) =>
plugin('Mock mailer').register(async ({ mailer }) => {
mailer.send = send
Expand Down
1 change: 1 addition & 0 deletions packages/tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"faker": "^4.1.0",
"jest": "^26.0.1",
"supertest": "^4.0.2",
"supertest-session": "^4.1.0",
"typescript": "^4.2.4"
},
"scripts": {
Expand Down
175 changes: 175 additions & 0 deletions packages/tests/packages/cms/admin.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { cms } from '@tensei/cms'
import SupertestSession from 'supertest-session'
import Supertest, { SuperTest as SI } from 'supertest'
import { setup, fakeUser, setupFakeMailer, getFakeMailer } from './setup'

export const getCmsCsrfToken = async (client: SI<any>): Promise<string> => {
const response = await client.get(`/cms/api/csrf`)

return response.headers['set-cookie'][0].split(';')[0].split('=')[1]
}

test('can passwordlessly register a new administrator user', async () => {
const mailerMock = getFakeMailer()

const email = fakeUser().email

const {
app,
ctx: {
orm: { em }
}
} = await setup([cms().plugin(), setupFakeMailer(mailerMock)], false)

const client = (SupertestSession(app) as unknown) as SI<any>

const csrf = await getCmsCsrfToken(client)

// Clear all existing administrators and passwordless tokens.
await em.nativeDelete('AdminToken', {})
await em.nativeDelete('AdminUser', {})

const response = await client
.post('/cms/api/passwordless/email/register')
.set('X-XSRF-TOKEN', csrf)
.send({
email
})

expect(response.status).toBe(204)

const [{ token }] = await em.find<{
token: string
}>('AdminToken', {})

const loginResponse = await client.get(
`/cms/api/passwordless/token/${token}`
)

expect(loginResponse.status).toBe(302)
expect(loginResponse.headers['location']).toBe('/cms')
})

test('cannot register another administrator if a super admin already exists', async () => {
const mailerMock = getFakeMailer()

const email = fakeUser().email

const {
app,
ctx: {
orm: { em }
}
} = await setup([cms().plugin(), setupFakeMailer(mailerMock)], false)

const client = (SupertestSession(app) as unknown) as SI<any>

const csrf = await getCmsCsrfToken(client)

// Clear all existing administrators and passwordless tokens.
await em.nativeDelete('AdminToken', {})
await em.nativeDelete('AdminUser', {})

await client
.post('/cms/api/passwordless/email/register')
.set('X-XSRF-TOKEN', csrf)
.send({
email
})
// attempt to register an administrator again
const response = await client
.post('/cms/api/passwordless/email/register')
.set('X-XSRF-TOKEN', csrf)
.send({
email
})

expect(response.status).toBe(400)
expect(response.body.message).toBe('Unauthorized.')
})

test('can passwordlessly login an existing administrator user', async () => {
const mailerMock = getFakeMailer()

const email = fakeUser().email

const {
app,
ctx: {
orm: { em }
}
} = await setup([cms().plugin(), setupFakeMailer(mailerMock)], false)

const client = (SupertestSession(app) as unknown) as SI<any>

const csrf = await getCmsCsrfToken(client)

// Clear all existing administrators and passwordless tokens.
await em.nativeDelete('AdminToken', {})
await em.nativeDelete('AdminUser', {})

await client
.post('/cms/api/passwordless/email/register')
.set('X-XSRF-TOKEN', csrf)
.send({
email
})

// clear registration token
await em.nativeDelete('AdminToken', {})

const response = await client
.post('/cms/api/passwordless/email/login')
.set('X-XSRF-TOKEN', csrf)
.send({
email
})

const [{ token }] = await em.find<{
token: string
}>('AdminToken', {})

const loginResponse = await client.get(
`/cms/api/passwordless/token/${token}`
)

expect(loginResponse.status).toBe(302)
expect(loginResponse.headers['location']).toBe('/cms')
})

test('redirects user to login when token is invalid or malformed', async () => {
const mailerMock = getFakeMailer()

const email = fakeUser().email

const {
app,
ctx: {
orm: { em }
}
} = await setup([cms().plugin(), setupFakeMailer(mailerMock)], false)

const client = (SupertestSession(app) as unknown) as SI<any>

const csrf = await getCmsCsrfToken(client)

// Clear all existing administrators and passwordless tokens.
await em.nativeDelete('AdminToken', {})
await em.nativeDelete('AdminUser', {})

await client
.post('/cms/api/passwordless/email/register')
.set('X-XSRF-TOKEN', csrf)
.send({
email
})

const loginResponse = await client.get(
`/cms/api/passwordless/token/WRONG_TOKEN`
)

expect(loginResponse.status).toBe(302)
expect(loginResponse.headers['location']).toBe(
'/cms/auth/login?error=Your%20login%20credentials%20are%20invalid.%20Please%20try%20again.'
)
})
1 change: 1 addition & 0 deletions packages/tests/packages/cms/setup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../../../helpers'
7 changes: 1 addition & 6 deletions packages/tests/packages/media/uploads.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,7 @@ test.skip('Cannot upload files larger than max file size', async () => {
})

test('Can upload files using the rest plugin', async () => {
const {
app,
ctx: {
orm: { em }
}
} = await setup(100000000, 48)
const { app } = await setup(100000000, 48)

const response = await Supertest(app)
.post('/files/upload')
Expand Down
11 changes: 10 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7551,7 +7551,7 @@ cookie@^0.4.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==

cookiejar@^2.1.0:
cookiejar@^2.1.0, cookiejar@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
Expand Down Expand Up @@ -19748,6 +19748,15 @@ superagent@^3.8.3:
qs "^6.5.1"
readable-stream "^2.3.5"

supertest-session@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/supertest-session/-/supertest-session-4.1.0.tgz#81d851ca311e12cc0b34c294012615649a55c159"
integrity sha512-zJmc2+WBpT772Pk6InGg90n0l1E+8rr5ue8PAyxefIEJWqbrn0RC02brrw7EC1wecoY+UH/AaQxMeo3sPrnPPA==
dependencies:
cookiejar "^2.1.2"
methods "^1.1.2"
object-assign "^4.0.1"

supertest@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/supertest/-/supertest-4.0.2.tgz#c2234dbdd6dc79b6f15b99c8d6577b90e4ce3f36"
Expand Down

0 comments on commit 88ff195

Please sign in to comment.