Merge branch 'feature/global-user-management' of github.com:Budibase/budibase into feature/global-user-management
This commit is contained in:
commit
a2c7ea9ba4
22 changed files with 259 additions and 217 deletions
|
@ -26,7 +26,7 @@ static_resources:
|
||||||
cluster: redis-service
|
cluster: redis-service
|
||||||
prefix_rewrite: "/"
|
prefix_rewrite: "/"
|
||||||
|
|
||||||
- match: { prefix: "/api/admin" }
|
- match: { prefix: "/api/admin/" }
|
||||||
route:
|
route:
|
||||||
cluster: worker-dev
|
cluster: worker-dev
|
||||||
|
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
static_resources:
|
|
||||||
listeners:
|
|
||||||
- name: main_listener
|
|
||||||
address:
|
|
||||||
socket_address: { address: 0.0.0.0, port_value: 10000 }
|
|
||||||
filter_chains:
|
|
||||||
- filters:
|
|
||||||
- name: envoy.filters.network.http_connection_manager
|
|
||||||
typed_config:
|
|
||||||
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
|
||||||
stat_prefix: ingress
|
|
||||||
codec_type: auto
|
|
||||||
route_config:
|
|
||||||
name: local_route
|
|
||||||
virtual_hosts:
|
|
||||||
- name: local_services
|
|
||||||
domains: ["*"]
|
|
||||||
routes:
|
|
||||||
- match: { prefix: "/db/" }
|
|
||||||
route:
|
|
||||||
cluster: couchdb-service
|
|
||||||
prefix_rewrite: "/"
|
|
||||||
|
|
||||||
- match: { prefix: "/cache/" }
|
|
||||||
route:
|
|
||||||
cluster: redis-service
|
|
||||||
prefix_rewrite: "/"
|
|
||||||
|
|
||||||
- match: { prefix: "/api/" }
|
|
||||||
route:
|
|
||||||
cluster: server-dev
|
|
||||||
|
|
||||||
- match: { prefix: "/app_" }
|
|
||||||
route:
|
|
||||||
cluster: server-dev
|
|
||||||
|
|
||||||
- match: { prefix: "/builder/" }
|
|
||||||
route:
|
|
||||||
cluster: builder-dev
|
|
||||||
|
|
||||||
- match: { prefix: "/builder" }
|
|
||||||
route:
|
|
||||||
cluster: builder-dev
|
|
||||||
prefix_rewrite: "/builder/"
|
|
||||||
|
|
||||||
# minio is on the default route because this works
|
|
||||||
# best, minio + AWS SDK doesn't handle path proxy
|
|
||||||
- match: { prefix: "/" }
|
|
||||||
route:
|
|
||||||
cluster: minio-service
|
|
||||||
|
|
||||||
http_filters:
|
|
||||||
- name: envoy.filters.http.router
|
|
||||||
|
|
||||||
clusters:
|
|
||||||
- name: minio-service
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: minio-service
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: minio-service
|
|
||||||
port_value: 9000
|
|
||||||
|
|
||||||
- name: couchdb-service
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: couchdb-service
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: couchdb-service
|
|
||||||
port_value: 5984
|
|
||||||
|
|
||||||
- name: redis-service
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: redis-service
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: redis-service
|
|
||||||
port_value: 6379
|
|
||||||
|
|
||||||
- name: server-dev
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: server-dev
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: host.docker.internal
|
|
||||||
port_value: 4001
|
|
||||||
|
|
||||||
- name: builder-dev
|
|
||||||
connect_timeout: 15s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: builder-dev
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: host.docker.internal
|
|
||||||
port_value: 3000
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ const JwtStrategy = require("passport-jwt").Strategy
|
||||||
// const GoogleStrategy = require("passport-google-oauth").Strategy
|
// const GoogleStrategy = require("passport-google-oauth").Strategy
|
||||||
const CouchDB = require("./db")
|
const CouchDB = require("./db")
|
||||||
const { StaticDatabases } = require("./db/utils")
|
const { StaticDatabases } = require("./db/utils")
|
||||||
const { jwt, local, google } = require("./middleware")
|
const { jwt, local, google, authenticated } = require("./middleware")
|
||||||
const { Cookies, UserStatus } = require("./constants")
|
const { Cookies, UserStatus } = require("./constants")
|
||||||
const { hash, compare } = require("./hashing")
|
const { hash, compare } = require("./hashing")
|
||||||
const { getAppId, setCookie } = require("./utils")
|
const { getAppId, setCookie } = require("./utils")
|
||||||
|
@ -45,4 +45,5 @@ module.exports = {
|
||||||
compare,
|
compare,
|
||||||
getAppId,
|
getAppId,
|
||||||
setCookie,
|
setCookie,
|
||||||
|
authenticated,
|
||||||
}
|
}
|
||||||
|
|
53
packages/auth/src/middleware/authenticated.js
Normal file
53
packages/auth/src/middleware/authenticated.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
const CouchDB = require("../db")
|
||||||
|
const { Cookies } = require("../constants")
|
||||||
|
const { getAppId, setCookie, getCookie } = require("../utils")
|
||||||
|
const { StaticDatabases } = require("../db/utils")
|
||||||
|
|
||||||
|
async function setCurrentAppContext(ctx) {
|
||||||
|
let role = "PUBLIC"
|
||||||
|
|
||||||
|
// Current app cookie
|
||||||
|
let appId = getAppId(ctx)
|
||||||
|
if (!appId) {
|
||||||
|
ctx.user = {
|
||||||
|
role,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentAppCookie = getCookie(ctx, Cookies.CurrentApp, { decrypt: true })
|
||||||
|
const appIdChanged = appId && currentAppCookie.appId !== appId
|
||||||
|
if (appIdChanged) {
|
||||||
|
try {
|
||||||
|
// get roles for user from global DB
|
||||||
|
const db = new CouchDB(StaticDatabases.USER)
|
||||||
|
const user = await db.get(ctx.user)
|
||||||
|
role = user.roles[appId]
|
||||||
|
} catch (err) {
|
||||||
|
// no user exists
|
||||||
|
}
|
||||||
|
} else if (currentAppCookie.appId) {
|
||||||
|
appId = currentAppCookie.appId
|
||||||
|
}
|
||||||
|
setCookie(ctx, { appId, role }, Cookies.CurrentApp, { encrypt: true })
|
||||||
|
return appId
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = async (ctx, next) => {
|
||||||
|
try {
|
||||||
|
// check the actual user is authenticated first
|
||||||
|
const authCookie = getCookie(ctx, Cookies.Auth, { decrypt: true })
|
||||||
|
|
||||||
|
if (authCookie) {
|
||||||
|
ctx.isAuthenticated = true
|
||||||
|
ctx.user = authCookie._id
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.appId = await setCurrentAppContext(ctx)
|
||||||
|
|
||||||
|
await next()
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
ctx.throw(err.status || 403, err.text)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
const jwt = require("./passport/jwt")
|
const jwt = require("./passport/jwt")
|
||||||
const local = require("./passport/local")
|
const local = require("./passport/local")
|
||||||
const google = require("./passport/google")
|
const google = require("./passport/google")
|
||||||
|
const authenticated = require("./authenticated")
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
google,
|
google,
|
||||||
jwt,
|
jwt,
|
||||||
local,
|
local,
|
||||||
|
authenticated,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
const { DocumentTypes, SEPARATOR } = require("./db/utils")
|
const { DocumentTypes, SEPARATOR } = require("./db/utils")
|
||||||
|
const jwt = require("jsonwebtoken")
|
||||||
|
const { options } = require("./middleware/passport/jwt")
|
||||||
|
|
||||||
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
||||||
|
|
||||||
|
@ -39,6 +41,23 @@ exports.getAppId = ctx => {
|
||||||
return appId
|
return appId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a cookie from context, and decrypt if necessary.
|
||||||
|
* @param {object} ctx The request which is to be manipulated.
|
||||||
|
* @param {string} name The name of the cookie to get.
|
||||||
|
* @param {object} options options .
|
||||||
|
*/
|
||||||
|
exports.getCookie = (ctx, value, options = {}) => {
|
||||||
|
const cookie = ctx.cookies.get(value)
|
||||||
|
|
||||||
|
if (!cookie) return
|
||||||
|
|
||||||
|
if (!options.decrypt) return cookie
|
||||||
|
|
||||||
|
const payload = jwt.verify(cookie, process.env.JWT_SECRET)
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a cookie for the request, has a hardcoded expiry.
|
* Store a cookie for the request, has a hardcoded expiry.
|
||||||
* @param {object} ctx The request which is to be manipulated.
|
* @param {object} ctx The request which is to be manipulated.
|
||||||
|
@ -52,6 +71,11 @@ exports.setCookie = (ctx, value, name = "builder") => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
ctx.cookies.set(name)
|
ctx.cookies.set(name)
|
||||||
} else {
|
} else {
|
||||||
|
if (options.encrypt) {
|
||||||
|
value = jwt.sign(value, process.env.JWT_SECRET, {
|
||||||
|
expiresIn: "1 day",
|
||||||
|
})
|
||||||
|
}
|
||||||
ctx.cookies.set(name, value, {
|
ctx.cookies.set(name, value, {
|
||||||
expires,
|
expires,
|
||||||
path: "/",
|
path: "/",
|
||||||
|
|
|
@ -20,9 +20,9 @@ export const get = apiCall("GET")
|
||||||
export const patch = apiCall("PATCH")
|
export const patch = apiCall("PATCH")
|
||||||
export const del = apiCall("DELETE")
|
export const del = apiCall("DELETE")
|
||||||
export const put = apiCall("PUT")
|
export const put = apiCall("PUT")
|
||||||
export const getBuilderCookie = async () => {
|
// export const getBuilderCookie = async () => {
|
||||||
await post("/api/builder/login", {})
|
// await post("/api/builder/login", {})
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
post: apiCall("POST"),
|
post: apiCall("POST"),
|
||||||
|
@ -30,5 +30,5 @@ export default {
|
||||||
patch: apiCall("PATCH"),
|
patch: apiCall("PATCH"),
|
||||||
delete: apiCall("DELETE"),
|
delete: apiCall("DELETE"),
|
||||||
put: apiCall("PUT"),
|
put: apiCall("PUT"),
|
||||||
getBuilderCookie,
|
// getBuilderCookie,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { derived, writable } from "svelte/store"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
import { FrontendTypes, LAYOUT_NAMES } from "../constants"
|
import { FrontendTypes, LAYOUT_NAMES } from "../constants"
|
||||||
import { findComponent } from "./storeUtils"
|
import { findComponent } from "./storeUtils"
|
||||||
import { getBuilderCookie } from "./api"
|
// import { getBuilderCookie } from "./api"
|
||||||
|
|
||||||
export const store = getFrontendStore()
|
export const store = getFrontendStore()
|
||||||
export const automationStore = getAutomationStore()
|
export const automationStore = getAutomationStore()
|
||||||
|
@ -59,7 +59,7 @@ export const selectedAccessRole = writable("BASIC")
|
||||||
export const initialise = async () => {
|
export const initialise = async () => {
|
||||||
try {
|
try {
|
||||||
// TODO this needs to be replaced by a real login
|
// TODO this needs to be replaced by a real login
|
||||||
await getBuilderCookie()
|
// await getBuilderCookie()
|
||||||
await analytics.activate()
|
await analytics.activate()
|
||||||
analytics.captureEvent("Builder Started")
|
analytics.captureEvent("Builder Started")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
52
packages/builder/src/components/login/LoginForm.svelte
Normal file
52
packages/builder/src/components/login/LoginForm.svelte
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<script>
|
||||||
|
import { Button, Label, Input, TextArea, Spacer } from "@budibase/bbui"
|
||||||
|
import { notifier } from "builderStore/store/notifications"
|
||||||
|
import { auth } from "stores/backend"
|
||||||
|
|
||||||
|
let username = ""
|
||||||
|
let password = ""
|
||||||
|
|
||||||
|
async function login() {
|
||||||
|
try {
|
||||||
|
const json = await auth.login({
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
})
|
||||||
|
notifier.success("Logged in successfully.")
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
notifier.danger(`Error logging in: ${err}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createTestUser() {
|
||||||
|
try {
|
||||||
|
const json = await auth.createUser({
|
||||||
|
email: "test@test.com",
|
||||||
|
password: "test",
|
||||||
|
roles: {},
|
||||||
|
})
|
||||||
|
notifier.success("Test user created")
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form on:submit|preventDefault>
|
||||||
|
<Spacer large />
|
||||||
|
<Label small>Email</Label>
|
||||||
|
<Input outline bind:value={username} />
|
||||||
|
<Spacer large />
|
||||||
|
<Label small>Password</Label>
|
||||||
|
<Input outline type="password" on:change bind:value={password} />
|
||||||
|
<Spacer large />
|
||||||
|
<Button primary on:click={login}>Login</Button>
|
||||||
|
<Button secondary on:click={createTestUser}>Create Test User</Button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
form {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
</style>
|
1
packages/builder/src/components/login/index.js
Normal file
1
packages/builder/src/components/login/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { LoginForm } from "./LoginForm.svelte"
|
|
@ -7,15 +7,20 @@
|
||||||
CommunityIcon,
|
CommunityIcon,
|
||||||
BugIcon,
|
BugIcon,
|
||||||
} from "components/common/Icons"
|
} from "components/common/Icons"
|
||||||
|
import LoginForm from "components/login/LoginForm.svelte"
|
||||||
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte"
|
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte"
|
||||||
import Logo from "/assets/budibase-logo.svg"
|
import Logo from "/assets/budibase-logo.svg"
|
||||||
|
import { auth } from "stores/backend"
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if $auth.user}
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="ui-nav">
|
<div class="ui-nav">
|
||||||
<div class="home-logo"><img src={Logo} alt="Budibase icon" /></div>
|
<div class="home-logo">
|
||||||
|
<img src={Logo} alt="Budibase icon" />
|
||||||
|
</div>
|
||||||
<div class="nav-section">
|
<div class="nav-section">
|
||||||
<div class="nav-top">
|
<div class="nav-top">
|
||||||
<Link icon={AppsIcon} title="Apps" href="/" active />
|
<Link icon={AppsIcon} title="Apps" href="/" active />
|
||||||
|
@ -45,6 +50,11 @@
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{:else}
|
||||||
|
<section class="login">
|
||||||
|
<LoginForm />
|
||||||
|
</section>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.root {
|
.root {
|
||||||
|
@ -55,6 +65,14 @@
|
||||||
background: var(--grey-1);
|
background: var(--grey-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
32
packages/builder/src/stores/backend/auth.js
Normal file
32
packages/builder/src/stores/backend/auth.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { writable, get } from "svelte/store"
|
||||||
|
import api from "../../builderStore/api"
|
||||||
|
|
||||||
|
export function createAuthStore() {
|
||||||
|
const { subscribe, set } = writable({})
|
||||||
|
|
||||||
|
const user = localStorage.getItem("auth:user")
|
||||||
|
if (user) set({ user: JSON.parse(user) })
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
login: async creds => {
|
||||||
|
const response = await api.post(`/api/admin/auth`, creds)
|
||||||
|
const json = await response.json()
|
||||||
|
if (json.user) {
|
||||||
|
localStorage.setItem("auth:user", JSON.stringify(json.user))
|
||||||
|
set({ user: json.user })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logout: async () => {
|
||||||
|
const response = await api.post(`/api/auth/logout`)
|
||||||
|
const json = await response.json()
|
||||||
|
set({ user: false })
|
||||||
|
},
|
||||||
|
createUser: async user => {
|
||||||
|
const response = await api.post(`/api/admin/users`, user)
|
||||||
|
const json = await response.json()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const auth = createAuthStore()
|
|
@ -7,3 +7,4 @@ export { roles } from "./roles"
|
||||||
export { datasources } from "./datasources"
|
export { datasources } from "./datasources"
|
||||||
export { integrations } from "./integrations"
|
export { integrations } from "./integrations"
|
||||||
export { queries } from "./queries"
|
export { queries } from "./queries"
|
||||||
|
export { auth } from "./auth"
|
||||||
|
|
|
@ -70,10 +70,10 @@ exports.authenticate = async ctx => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.builderLogin = async ctx => {
|
// exports.builderLogin = async ctx => {
|
||||||
await setBuilderToken(ctx)
|
// await setBuilderToken(ctx)
|
||||||
ctx.status = 200
|
// ctx.status = 200
|
||||||
}
|
// }
|
||||||
|
|
||||||
exports.fetchSelf = async ctx => {
|
exports.fetchSelf = async ctx => {
|
||||||
const { userId, appId } = ctx.user
|
const { userId, appId } = ctx.user
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const authenticated = require("../middleware/authenticated")
|
const { authenticated } = require("@budibase/auth")
|
||||||
const compress = require("koa-compress")
|
const compress = require("koa-compress")
|
||||||
const zlib = require("zlib")
|
const zlib = require("zlib")
|
||||||
const { mainRoutes, authRoutes, staticRoutes } = require("./routes")
|
const { mainRoutes, authRoutes, staticRoutes } = require("./routes")
|
||||||
|
|
|
@ -7,7 +7,7 @@ const router = Router()
|
||||||
|
|
||||||
router.post("/api/authenticate", controller.authenticate)
|
router.post("/api/authenticate", controller.authenticate)
|
||||||
// TODO: this is a hack simply to make sure builder has a cookie until auth reworked
|
// TODO: this is a hack simply to make sure builder has a cookie until auth reworked
|
||||||
router.post("/api/builder/login", authorized(BUILDER), controller.builderLogin)
|
// router.post("/api/builder/login", authorized(BUILDER), controller.builderLogin)
|
||||||
// doesn't need authorization as can only fetch info about self
|
// doesn't need authorization as can only fetch info about self
|
||||||
router.get("/api/self", controller.fetchSelf)
|
router.get("/api/self", controller.fetchSelf)
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
|
|
||||||
const role = ctx.user.role
|
const role = ctx.user.role
|
||||||
const isAdmin = ADMIN_ROLES.includes(role._id)
|
const isAdmin = ADMIN_ROLES.includes(role._id)
|
||||||
const isAuthed = ctx.auth.authenticated
|
// const isAuthed = ctx.auth.authenticated
|
||||||
|
const isAuthed = ctx.isAuthenticated
|
||||||
|
|
||||||
const { basePermissions, permissions } = await getUserPermissions(
|
const { basePermissions, permissions } = await getUserPermissions(
|
||||||
ctx.appId,
|
ctx.appId,
|
||||||
|
@ -50,11 +51,11 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
// this may need to change in the future, right now only admins
|
// this may need to change in the future, right now only admins
|
||||||
// can have access to builder features, this is hard coded into
|
// can have access to builder features, this is hard coded into
|
||||||
// our rules
|
// our rules
|
||||||
if (isAdmin && isAuthed) {
|
// if (isAdmin && isAuthed) {
|
||||||
return next()
|
// return next()
|
||||||
} else if (permType === PermissionTypes.BUILDER) {
|
// } else if (permType === PermissionTypes.BUILDER) {
|
||||||
return ctx.throw(403, "Not Authorized")
|
// return ctx.throw(403, "Not Authorized")
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (
|
if (
|
||||||
hasResource(ctx) &&
|
hasResource(ctx) &&
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { passport } = require("@budibase/auth")
|
const { passport, Cookies } = require("@budibase/auth")
|
||||||
|
|
||||||
exports.authenticate = async (ctx, next) => {
|
exports.authenticate = async (ctx, next) => {
|
||||||
return passport.authenticate("local", async (err, user) => {
|
return passport.authenticate("local", async (err, user) => {
|
||||||
|
@ -9,13 +9,24 @@ exports.authenticate = async (ctx, next) => {
|
||||||
const expires = new Date()
|
const expires = new Date()
|
||||||
expires.setDate(expires.getDate() + 1)
|
expires.setDate(expires.getDate() + 1)
|
||||||
|
|
||||||
ctx.cookies.set("budibase:auth", user.token, {
|
if (!user) {
|
||||||
|
ctx.body = { success: false, user }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.cookies.set(Cookies.Auth, user.token, {
|
||||||
expires,
|
expires,
|
||||||
path: "/",
|
path: "/",
|
||||||
httpOnly: false,
|
httpOnly: false,
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.body = { success: true }
|
delete user.token
|
||||||
|
|
||||||
|
ctx.body = { success: true, user }
|
||||||
})(ctx, next)
|
})(ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.googleAuth = async (ctx, next) => {
|
||||||
|
// return passport.authenticate("google")
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../../controllers/admin")
|
const controller = require("../../controllers/admin")
|
||||||
const authenticated = require("../../../middleware/authenticated")
|
|
||||||
const joiValidator = require("../../../middleware/joi-validator")
|
const joiValidator = require("../../../middleware/joi-validator")
|
||||||
|
const { authenticated } = require("@budibase/auth")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
|
const { passport } = require("@budibase/auth")
|
||||||
const authController = require("../controllers/auth")
|
const authController = require("../controllers/auth")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router.post("/api/auth/authenticate", authController.authenticate)
|
router
|
||||||
|
.post("/api/admin/auth", authController.authenticate)
|
||||||
|
.get("/api/auth/google", passport.authenticate("google"))
|
||||||
|
.get(
|
||||||
|
"/api/auth/google/callback",
|
||||||
|
passport.authenticate("google", {
|
||||||
|
successRedirect: "/app",
|
||||||
|
failureRedirect: "/",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
const { passport, getAppId, setCookie, Cookies } = require("@budibase/auth")
|
|
||||||
|
|
||||||
module.exports = async (ctx, next) => {
|
|
||||||
// do everything we can to make sure the appId is held correctly
|
|
||||||
let appId = getAppId(ctx)
|
|
||||||
const cookieAppId = ctx.cookies.get(Cookies.CurrentApp)
|
|
||||||
// const builtinRoles = getBuiltinRoles()
|
|
||||||
if (appId && cookieAppId !== appId) {
|
|
||||||
setCookie(ctx, appId, Cookies.CurrentApp)
|
|
||||||
} else if (cookieAppId) {
|
|
||||||
appId = cookieAppId
|
|
||||||
}
|
|
||||||
|
|
||||||
return next()
|
|
||||||
|
|
||||||
// return passport.authenticate("jwt", async (err, user) => {
|
|
||||||
// if (err) {
|
|
||||||
// return ctx.throw(err.status || 403, err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// try {
|
|
||||||
// ctx.appId = appId
|
|
||||||
// ctx.isAuthenticated = true
|
|
||||||
// // TODO: introduce roles again
|
|
||||||
// ctx.user = user
|
|
||||||
// await next()
|
|
||||||
// } catch (err) {
|
|
||||||
// console.log(err)
|
|
||||||
// ctx.throw(err.status || 403, err.text)
|
|
||||||
// }
|
|
||||||
// })(ctx, next)
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
/**
|
|
||||||
* Check the user token, used when creating admin resources, like for example
|
|
||||||
* a global user record.
|
|
||||||
*/
|
|
||||||
module.exports = async (ctx, next) => {
|
|
||||||
return next()
|
|
||||||
}
|
|
Loading…
Reference in a new issue