Add database test configuration to auth package
This commit is contained in:
parent
6f1d995cc8
commit
ea7ebafe12
|
@ -27,9 +27,17 @@
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"zlib": "^1.0.5"
|
"zlib": "^1.0.5"
|
||||||
},
|
},
|
||||||
|
"jest": {
|
||||||
|
"setupFiles": [
|
||||||
|
"./scripts/jestSetup.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ioredis-mock": "^5.5.5",
|
"ioredis-mock": "^5.5.5",
|
||||||
"jest": "^26.6.3"
|
"jest": "^26.6.3",
|
||||||
|
"pouchdb-adapter-memory": "^7.2.2",
|
||||||
|
"pouchdb": "^7.2.1",
|
||||||
|
"pouchdb-all-dbs": "^1.0.2"
|
||||||
},
|
},
|
||||||
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
const env = require("../src/environment")
|
||||||
|
|
||||||
|
env._set("NODE_ENV", "jest")
|
||||||
|
env._set("JWT_SECRET", "test-jwtsecret")
|
||||||
|
env._set("LOG_LEVEL", "silent")
|
|
@ -17,4 +17,8 @@ module.exports = {
|
||||||
MINIO_URL: process.env.MINIO_URL,
|
MINIO_URL: process.env.MINIO_URL,
|
||||||
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
||||||
isTest,
|
isTest,
|
||||||
|
_set(key, value) {
|
||||||
|
process.env[key] = value
|
||||||
|
module.exports[key] = value
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Mock data
|
// Mock data
|
||||||
|
|
||||||
const { data } = require("./utilities")
|
const { data } = require("./utilities/mock-data")
|
||||||
|
|
||||||
const googleConfig = {
|
const googleConfig = {
|
||||||
callbackURL: "http://somecallbackurl",
|
callbackURL: "http://somecallbackurl",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Mock data
|
// Mock data
|
||||||
|
|
||||||
const { data } = require("./utilities")
|
const { data } = require("./utilities/mock-data")
|
||||||
|
|
||||||
const issuer = "mockIssuer"
|
const issuer = "mockIssuer"
|
||||||
const sub = "mockSub"
|
const sub = "mockSub"
|
||||||
|
|
|
@ -1,18 +1,151 @@
|
||||||
// Mock data
|
// Mock data
|
||||||
|
|
||||||
|
require("./utilities/test-config")
|
||||||
|
|
||||||
|
const database = require("../../../db")
|
||||||
const { authenticateThirdParty } = require("../third-party-common")
|
const { authenticateThirdParty } = require("../third-party-common")
|
||||||
|
const { data } = require("./utilities/mock-data")
|
||||||
|
|
||||||
|
const {
|
||||||
|
StaticDatabases,
|
||||||
|
generateGlobalUserID
|
||||||
|
} = require("../../../db/utils")
|
||||||
|
const { newid } = require("../../../hashing")
|
||||||
|
|
||||||
|
let db
|
||||||
|
|
||||||
|
const done = jest.fn()
|
||||||
|
|
||||||
|
const getErrorMessage = () => {
|
||||||
|
return done.mock.calls[0][2].message
|
||||||
|
}
|
||||||
|
|
||||||
describe("third party common", () => {
|
describe("third party common", () => {
|
||||||
|
|
||||||
describe("authenticateThirdParty", () => {
|
describe("authenticateThirdParty", () => {
|
||||||
it("", () => {
|
let thirdPartyUser
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
db = database.getDB(StaticDatabases.GLOBAL.name)
|
||||||
|
thirdPartyUser = data.buildThirdPartyUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
await db.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("validation", () => {
|
||||||
|
const testValidation = async (message) => {
|
||||||
|
await authenticateThirdParty(thirdPartyUser, false, done)
|
||||||
|
expect(done.mock.calls.length).toBe(1)
|
||||||
|
expect(getErrorMessage()).toContain(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
it("provider fails", async () => {
|
||||||
|
delete thirdPartyUser.provider
|
||||||
|
testValidation("third party user provider required")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("user id fails", async () => {
|
||||||
|
delete thirdPartyUser.userId
|
||||||
|
testValidation("third party user id required")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("email fails", async () => {
|
||||||
|
delete thirdPartyUser.email
|
||||||
|
testValidation("third party user email required")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("syncUser", () => {
|
const expectUserIsAuthenticated = () => {
|
||||||
it("", () => {
|
const user = done.mock.calls[0][1]
|
||||||
|
expect(user).toBeDefined()
|
||||||
|
expect(user._id).toBeDefined()
|
||||||
|
expect(user._rev).toBeDefined()
|
||||||
|
expect(user.token).toBeDefined()
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectUserIsSynced = (user, thirdPartyUser) => {
|
||||||
|
expect(user.provider).toBe(thirdPartyUser.provider)
|
||||||
|
expect(user.email).toBe(thirdPartyUser.email)
|
||||||
|
expect(user.firstName).toBe(thirdPartyUser.profile.name.givenName)
|
||||||
|
expect(user.lastName).toBe(thirdPartyUser.profile.name.familyName)
|
||||||
|
expect(user.thirdPartyProfile).toStrictEqual(thirdPartyUser.profile._json)
|
||||||
|
expect(user.oauth2).toStrictEqual(thirdPartyUser.oauth2)
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("when the user doesn't exist", () => {
|
||||||
|
describe("when a local account is required", () => {
|
||||||
|
it("returns an error message", async () => {
|
||||||
|
await authenticateThirdParty(thirdPartyUser, true, done)
|
||||||
|
expect(done.mock.calls.length).toBe(1)
|
||||||
|
expect(getErrorMessage()).toContain("Email does not yet exist. You must set up your local budibase account first.")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("when a local account isn't required", () => {
|
||||||
|
it("creates and authenticates the user", async () => {
|
||||||
|
await authenticateThirdParty(thirdPartyUser, false, done)
|
||||||
|
const user = expectUserIsAuthenticated()
|
||||||
|
expectUserIsSynced(user, thirdPartyUser)
|
||||||
|
expect(user.roles).toStrictEqual({})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("when the user exists", () => {
|
||||||
|
let dbUser
|
||||||
|
let id
|
||||||
|
let email
|
||||||
|
|
||||||
|
const createUser = async () => {
|
||||||
|
dbUser = {
|
||||||
|
_id: id,
|
||||||
|
email: email,
|
||||||
|
}
|
||||||
|
const response = await db.post(dbUser)
|
||||||
|
dbUser._rev = response.rev
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectUserIsUpdated = (user) => {
|
||||||
|
// id is unchanged
|
||||||
|
expect(user._id).toBe(id)
|
||||||
|
// user is updated
|
||||||
|
expect(user._rev).not.toBe(dbUser._rev)
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("exists by email", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
id = generateGlobalUserID(newid()) // random id
|
||||||
|
email = thirdPartyUser.email // matching email
|
||||||
|
await createUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("syncs and authenticates the user", async () => {
|
||||||
|
await authenticateThirdParty(thirdPartyUser, true, done)
|
||||||
|
|
||||||
|
const user = expectUserIsAuthenticated()
|
||||||
|
expectUserIsSynced(user, thirdPartyUser)
|
||||||
|
expectUserIsUpdated(user)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("exists by id", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
id = generateGlobalUserID(thirdPartyUser.userId) // matching id
|
||||||
|
email = "test@test.com" // random email
|
||||||
|
await createUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("syncs and authenticates the user", async () => {
|
||||||
|
await authenticateThirdParty(thirdPartyUser, true, done)
|
||||||
|
|
||||||
|
const user = expectUserIsAuthenticated()
|
||||||
|
expectUserIsSynced(user, thirdPartyUser)
|
||||||
|
expectUserIsUpdated(user)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
const PouchDB = require("pouchdb")
|
||||||
|
const allDbs = require("pouchdb-all-dbs")
|
||||||
|
const env = require("../../../../environment")
|
||||||
|
|
||||||
|
let POUCH_DB_DEFAULTS
|
||||||
|
|
||||||
|
// should always be test but good to do the sanity check
|
||||||
|
if (env.isTest()) {
|
||||||
|
PouchDB.plugin(require("pouchdb-adapter-memory"))
|
||||||
|
POUCH_DB_DEFAULTS = {
|
||||||
|
prefix: undefined,
|
||||||
|
adapter: "memory",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS)
|
||||||
|
|
||||||
|
allDbs(Pouch)
|
||||||
|
|
||||||
|
module.exports = Pouch
|
|
@ -7,6 +7,20 @@ const mockEmail = "mock@budibase.com"
|
||||||
const mockAccessToken = "mockAccessToken"
|
const mockAccessToken = "mockAccessToken"
|
||||||
const mockRefreshToken = "mockRefreshToken"
|
const mockRefreshToken = "mockRefreshToken"
|
||||||
|
|
||||||
|
const mockProvider = "mockProvider"
|
||||||
|
const mockProviderType = "mockProviderType"
|
||||||
|
|
||||||
|
const mockProfile = {
|
||||||
|
id: "mockId",
|
||||||
|
name: {
|
||||||
|
givenName: "mockGivenName",
|
||||||
|
familyName: "mockFamilyName",
|
||||||
|
},
|
||||||
|
_json: {
|
||||||
|
email: mockEmail,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const buildOauth2 = (
|
const buildOauth2 = (
|
||||||
accessToken = mockAccessToken,
|
accessToken = mockAccessToken,
|
||||||
refreshToken = mockRefreshToken
|
refreshToken = mockRefreshToken
|
||||||
|
@ -16,9 +30,9 @@ const buildOauth2 = (
|
||||||
})
|
})
|
||||||
|
|
||||||
const buildThirdPartyUser = (
|
const buildThirdPartyUser = (
|
||||||
provider,
|
provider = mockProvider,
|
||||||
providerType,
|
providerType = mockProviderType,
|
||||||
profile,
|
profile = mockProfile,
|
||||||
email = mockEmail,
|
email = mockEmail,
|
||||||
oauth2 = buildOauth2()
|
oauth2 = buildOauth2()
|
||||||
) => ({
|
) => ({
|
|
@ -0,0 +1,3 @@
|
||||||
|
const packageConfiguration = require("../../../../index")
|
||||||
|
const CouchDB = require("./db")
|
||||||
|
packageConfiguration.init(CouchDB)
|
|
@ -1,14 +1,11 @@
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const database = require("../../db")
|
const database = require("../../db")
|
||||||
const {
|
const { StaticDatabases, generateGlobalUserID } = require("../../db/utils")
|
||||||
StaticDatabases,
|
|
||||||
generateGlobalUserID,
|
|
||||||
ViewNames,
|
|
||||||
} = require("../../db/utils")
|
|
||||||
const { authError } = require("./utils")
|
const { authError } = require("./utils")
|
||||||
const { newid } = require("../../hashing")
|
const { newid } = require("../../hashing")
|
||||||
const { createASession } = require("../../security/sessions")
|
const { createASession } = require("../../security/sessions")
|
||||||
|
const { getGlobalUserByEmail } = require("../../utils")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common authentication logic for third parties. e.g. OAuth, OIDC.
|
* Common authentication logic for third parties. e.g. OAuth, OIDC.
|
||||||
|
@ -48,14 +45,7 @@ exports.authenticateThirdParty = async function (
|
||||||
|
|
||||||
// fallback to loading by email
|
// fallback to loading by email
|
||||||
if (!dbUser) {
|
if (!dbUser) {
|
||||||
const users = await db.query(`database/${ViewNames.USER_BY_EMAIL}`, {
|
dbUser = await getGlobalUserByEmail(thirdPartyUser.email)
|
||||||
key: thirdPartyUser.email,
|
|
||||||
include_docs: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (users.rows.length > 0) {
|
|
||||||
dbUser = users.rows[0].doc
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// exit early if there is still no user and auto creation is disabled
|
// exit early if there is still no user and auto creation is disabled
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue