Updating test cases and some re-work of the email system.

This commit is contained in:
mike12345567 2021-04-23 18:07:39 +01:00
parent d0072c28f8
commit 0dd46d12fa
18 changed files with 139 additions and 58 deletions

View File

@ -36,7 +36,7 @@ module.exports = {
buildAuthMiddleware: authenticated,
passport,
google,
jwt,
jwt: require("jsonwebtoken"),
},
StaticDatabases,
constants: require("./constants"),

View File

@ -1,6 +1,6 @@
const { Cookies } = require("../constants")
const database = require("../db")
const { getCookie } = require("../utils")
const { getCookie, clearCookie } = require("../utils")
const { StaticDatabases } = require("../db/utils")
module.exports = (noAuthPatterns = []) => {
@ -15,11 +15,20 @@ module.exports = (noAuthPatterns = []) => {
const authCookie = getCookie(ctx, Cookies.Auth)
if (authCookie) {
const db = database.getDB(StaticDatabases.GLOBAL.name)
const user = await db.get(authCookie.userId)
delete user.password
ctx.isAuthenticated = true
ctx.user = user
try {
const db = database.getDB(StaticDatabases.GLOBAL.name)
const user = await db.get(authCookie.userId)
delete user.password
ctx.isAuthenticated = true
ctx.user = user
} catch (err) {
// remove the cookie as the use does not exist anymore
clearCookie(ctx, Cookies.Auth)
}
}
// be explicit
if (ctx.isAuthenticated !== true) {
ctx.isAuthenticated = false
}
return next()

View File

@ -92,7 +92,7 @@ exports.setCookie = (ctx, value, name = "builder") => {
* Utility function, simply calls setCookie with an empty string for value
*/
exports.clearCookie = (ctx, name) => {
exports.setCookie(ctx, "", name)
exports.setCookie(ctx, null, name)
}
/**

View File

@ -93,7 +93,7 @@ describe("/queries", () => {
const query = await config.createQuery()
const res = await request
.get(`/api/queries/${query._id}`)
.set(await config.roleHeaders())
.set(await config.roleHeaders({}))
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.fields).toBeUndefined()

View File

@ -35,7 +35,11 @@ describe("/routing", () => {
})
const res = await request
.get(`/api/routing/client`)
.set(await config.roleHeaders("basic@test.com", BUILTIN_ROLE_IDS.BASIC))
.set(await config.roleHeaders({
email: "basic@test.com",
roleId: BUILTIN_ROLE_IDS.BASIC,
builder: false
}))
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.routes).toBeDefined()
@ -59,7 +63,11 @@ describe("/routing", () => {
})
const res = await request
.get(`/api/routing/client`)
.set(await config.roleHeaders("basic@test.com", BUILTIN_ROLE_IDS.POWER))
.set(await config.roleHeaders({
email: "basic@test.com",
roleId: BUILTIN_ROLE_IDS.POWER,
builder: false,
}))
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.routes).toBeDefined()

View File

@ -5,7 +5,9 @@ const { basicUser } = setup.structures
const workerRequests = require("../../../utilities/workerRequests")
jest.mock("../../../utilities/workerRequests", () => ({
getGlobalUsers: jest.fn(),
getGlobalUsers: jest.fn(() => {
return {}
}),
saveGlobalUser: jest.fn(() => {
const uuid = require("uuid/v4")
return {

View File

@ -46,7 +46,10 @@ exports.createRequest = (request, method, url, body) => {
}
exports.checkBuilderEndpoint = async ({ config, method, url, body }) => {
const headers = await config.login()
const headers = await config.login("test@test.com", "test", {
userId: "us_fail",
builder: false,
})
await exports
.createRequest(config.request, method, url, body)
.set(headers)
@ -62,9 +65,10 @@ exports.checkPermissionsEndpoint = async ({
failRole,
}) => {
const password = "PASSWORD"
await config.createUser("passUser@budibase.com", password, passRole)
const passHeader = await config.login("passUser@budibase.com", password, {
let user = await config.createUser("pass@budibase.com", password, passRole)
const passHeader = await config.login("pass@budibase.com", password, {
roleId: passRole,
userId: user.globalId,
})
await exports
@ -72,9 +76,10 @@ exports.checkPermissionsEndpoint = async ({
.set(passHeader)
.expect(200)
await config.createUser("failUser@budibase.com", password, failRole)
const failHeader = await config.login("failUser@budibase.com", password, {
user = await config.createUser("fail@budibase.com", password, failRole)
const failHeader = await config.login("fail@budibase.com", password, {
roleId: failRole,
userId: user.globalId,
})
await exports

View File

@ -3,10 +3,7 @@ const { Cookies } = require("@budibase/auth").constants
const { getRole } = require("../utilities/security/roles")
const { getGlobalUsers } = require("../utilities/workerRequests")
const { BUILTIN_ROLE_IDS } = require("../utilities/security/roles")
const {
getGlobalIDFromUserMetadataID,
generateUserMetadataID,
} = require("../db/utils")
const { generateUserMetadataID } = require("../db/utils")
module.exports = async (ctx, next) => {
// try to get the appID from the request
@ -31,8 +28,7 @@ module.exports = async (ctx, next) => {
appCookie.roleId === BUILTIN_ROLE_IDS.PUBLIC)
) {
// Different App ID means cookie needs reset, or if the same public user has logged in
const globalId = getGlobalIDFromUserMetadataID(ctx.user._id)
const globalUser = await getGlobalUsers(ctx, requestAppId, globalId)
const globalUser = await getGlobalUsers(ctx, requestAppId, ctx.user._id)
updateCookie = true
appId = requestAppId
if (globalUser.roles && globalUser.roles[requestAppId]) {

View File

@ -5,7 +5,7 @@ function mockWorker() {
jest.mock("../../utilities/workerRequests", () => ({
getGlobalUsers: () => {
return {
email: "us_uuid1",
_id: "us_uuid1",
roles: {
"app_test": "BASIC",
}
@ -67,7 +67,8 @@ class TestConfiguration {
setUser() {
this.ctx.user = {
userId: "ro_ta_user_us_uuid1",
userId: "us_uuid1",
_id: "us_uuid1",
}
}
@ -159,5 +160,4 @@ describe("Current app middleware", () => {
await checkExpected(false)
})
})
})

View File

@ -16,7 +16,10 @@ const supertest = require("supertest")
const { cleanup } = require("../../utilities/fileSystem")
const { Cookies } = require("@budibase/auth").constants
const { jwt } = require("@budibase/auth").auth
const { StaticDatabases } = require("@budibase/auth").db
const CouchDB = require("../../db")
const GLOBAL_USER_ID = "us_uuid1"
const EMAIL = "babs@babs.com"
const PASSWORD = "babs_password"
@ -57,7 +60,27 @@ class TestConfiguration {
return request.body
}
async globalUser(id = GLOBAL_USER_ID, builder = true) {
const db = new CouchDB(StaticDatabases.GLOBAL.name)
let existing
try {
existing = await db.get(id)
} catch (err) {
existing = {}
}
const user = {
_id: id,
...existing,
roles: {},
}
if (builder) {
user.builder = { global: true }
}
await db.put(user)
}
async init(appName = "test_application") {
await this.globalUser()
return this.createApp(appName)
}
@ -69,17 +92,14 @@ class TestConfiguration {
}
defaultHeaders() {
const user = {
userId: "ro_ta_user_us_uuid1",
builder: {
global: true,
},
const auth = {
userId: GLOBAL_USER_ID,
}
const app = {
roleId: BUILTIN_ROLE_IDS.BUILDER,
appId: this.appId,
}
const authToken = jwt.sign(user, env.JWT_SECRET)
const authToken = jwt.sign(auth, env.JWT_SECRET)
const appToken = jwt.sign(app, env.JWT_SECRET)
const headers = {
Accept: "application/json",
@ -104,14 +124,18 @@ class TestConfiguration {
return headers
}
async roleHeaders(email = EMAIL, roleId = BUILTIN_ROLE_IDS.ADMIN) {
async roleHeaders({
email = EMAIL,
roleId = BUILTIN_ROLE_IDS.ADMIN,
builder = false,
}) {
let user
try {
user = await this.createUser(email, PASSWORD, roleId)
} catch (err) {
// allow errors here
}
return this.login(email, PASSWORD, { roleId, userId: user._id })
return this.login(email, PASSWORD, { roleId, userId: user._id, builder })
}
async createApp(appName) {
@ -282,7 +306,9 @@ class TestConfiguration {
password = PASSWORD,
roleId = BUILTIN_ROLE_IDS.POWER
) {
return this._req(
const globalId = `us_${Math.random()}`
await this.globalUser(globalId, roleId === BUILTIN_ROLE_IDS.BUILDER)
const user = await this._req(
{
email,
password,
@ -291,28 +317,34 @@ class TestConfiguration {
null,
controllers.user.createMetadata
)
return {
...user,
globalId,
}
}
async login(email, password, { roleId, userId } = {}) {
if (!roleId) {
roleId = BUILTIN_ROLE_IDS.BUILDER
}
async login(email, password, { roleId, userId, builder } = {}) {
roleId = !roleId ? BUILTIN_ROLE_IDS.BUILDER : roleId
userId = !userId ? `us_uuid1` : userId
if (!this.request) {
throw "Server has not been opened, cannot login."
}
// make sure the user exists in the global DB
if (roleId !== BUILTIN_ROLE_IDS.PUBLIC) {
await this.globalUser(userId, builder)
}
if (!email || !password) {
await this.createUser()
}
// have to fake this
const user = {
userId: userId || `us_uuid1`,
email: email || EMAIL,
const auth = {
userId,
}
const app = {
roleId: roleId,
appId: this.appId,
}
const authToken = jwt.sign(user, env.JWT_SECRET)
const authToken = jwt.sign(auth, env.JWT_SECRET)
const appToken = jwt.sign(app, env.JWT_SECRET)
// returning necessary request headers

View File

@ -66,5 +66,9 @@ exports.sendEmail = async ctx => {
to: email,
html: await buildEmail(purpose, email, user),
}
await transport.sendMail(message)
const response = await transport.sendMail(message)
ctx.body = {
...response,
message: `Email sent to ${email}.`,
}
}

View File

@ -23,6 +23,13 @@ router
)
.use("/health", ctx => (ctx.status = 200))
.use(buildAuthMiddleware(NO_AUTH_ENDPOINTS))
// for now no public access is allowed to worker (bar health check)
.use((ctx, next) => {
if (!ctx.isAuthenticated) {
ctx.throw(403, "Unauthorized - no public worker access")
}
return next()
})
// error handling middleware
router.use(async (ctx, next) => {

View File

@ -27,3 +27,5 @@ router
.get("/api/admin/template/:ownerId", controller.fetchByOwner)
.get("/api/admin/template/:id", controller.find)
.delete("/api/admin/template/:id/:rev", controller.destroy)
module.exports = router

View File

@ -1,7 +1,17 @@
const userRoutes = require("./admin/users")
const configRoutes = require("./admin/configs")
const groupRoutes = require("./admin/groups")
const templateRoutes = require("./admin/templates")
const emailRoutes = require("./admin/email")
const authRoutes = require("./auth")
const appRoutes = require("./app")
exports.routes = [configRoutes, userRoutes, groupRoutes, authRoutes, appRoutes]
exports.routes = [
configRoutes,
userRoutes,
groupRoutes,
authRoutes,
appRoutes,
templateRoutes,
emailRoutes
]

View File

@ -36,12 +36,20 @@ class TestConfiguration {
return request.body
}
defaultHeaders() {
const user = {
userId: "us_uuid1",
async init() {
// create a test user
await this._req({
_id: "us_uuid1",
builder: {
global: true,
},
}
}, null, controllers.users.save)
}
defaultHeaders() {
const user = {
_id: "us_uuid1",
userId: "us_uuid1",
}
const authToken = jwt.sign(user, env.JWT_SECRET)
return {

View File

@ -8,18 +8,16 @@ const { join } = require("path")
const CouchDB = require("../../db")
const { getTemplateParams, StaticDatabases } = require("@budibase/auth").db
const TEMPLATE_PATH = join(__dirname, "..", "constants", "templates")
exports.EmailTemplates = {
[EmailTemplatePurpose.PASSWORD_RECOVERY]: readStaticFile(
join(TEMPLATE_PATH, "passwordRecovery.html")
join(__dirname, "passwordRecovery.html")
),
[EmailTemplatePurpose.INVITATION]: readStaticFile(
join(TEMPLATE_PATH, "invitation.html")
join(__dirname, "invitation.html")
),
[EmailTemplatePurpose.BASE]: readStaticFile(join(TEMPLATE_PATH, "base.html")),
[EmailTemplatePurpose.BASE]: readStaticFile(join(__dirname, "base.html")),
[EmailTemplatePurpose.STYLES]: readStaticFile(
join(TEMPLATE_PATH, "style.css")
join(__dirname, "style.css")
),
}

View File

@ -1,6 +1,6 @@
const nodemailer = require("nodemailer")
exports.createSMTPTransport = (config) => {
exports.createSMTPTransport = config => {
const options = {
port: config.port,
host: config.host,

View File

@ -1,4 +1,4 @@
const CouchDB = require("../../../db")
const CouchDB = require("../db")
const { getConfigParams, StaticDatabases } = require("@budibase/auth").db
const { Configs, TemplateBindings, LOGO_URL } = require("../constants")
const { checkSlashesInUrl } = require("./index")