chore: Migrate authentication to new tables (#1929)
This work provides a foundation for a more pluggable authentication system such as the one outlined in #1317. closes #1317
This commit is contained in:
@@ -37,10 +37,14 @@ services.push({
|
||||
function filterServices(team) {
|
||||
let output = services;
|
||||
|
||||
if (team && !team.googleId) {
|
||||
const providerNames = team
|
||||
? team.authenticationProviders.map((provider) => provider.name)
|
||||
: [];
|
||||
|
||||
if (team && !providerNames.includes("google")) {
|
||||
output = reject(output, (service) => service.id === "google");
|
||||
}
|
||||
if (team && !team.slackId) {
|
||||
if (team && !providerNames.includes("slack")) {
|
||||
output = reject(output, (service) => service.id === "slack");
|
||||
}
|
||||
if (!team || !team.guestSignin) {
|
||||
@@ -55,7 +59,7 @@ router.post("auth.config", async (ctx) => {
|
||||
// brand for the knowledge base and it's guest signin option is used for the
|
||||
// root login page.
|
||||
if (process.env.DEPLOYMENT !== "hosted") {
|
||||
const teams = await Team.findAll();
|
||||
const teams = await Team.scope("withAuthenticationProviders").findAll();
|
||||
|
||||
if (teams.length === 1) {
|
||||
const team = teams[0];
|
||||
@@ -70,7 +74,7 @@ router.post("auth.config", async (ctx) => {
|
||||
}
|
||||
|
||||
if (isCustomDomain(ctx.request.hostname)) {
|
||||
const team = await Team.findOne({
|
||||
const team = await Team.scope("withAuthenticationProviders").findOne({
|
||||
where: { domain: ctx.request.hostname },
|
||||
});
|
||||
|
||||
@@ -95,7 +99,7 @@ router.post("auth.config", async (ctx) => {
|
||||
) {
|
||||
const domain = parseDomain(ctx.request.hostname);
|
||||
const subdomain = domain ? domain.subdomain : undefined;
|
||||
const team = await Team.findOne({
|
||||
const team = await Team.scope("withAuthenticationProviders").findOne({
|
||||
where: { subdomain },
|
||||
});
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import Router from "koa-router";
|
||||
import { escapeRegExp } from "lodash";
|
||||
import { AuthenticationError, InvalidRequestError } from "../errors";
|
||||
import {
|
||||
UserAuthentication,
|
||||
AuthenticationProvider,
|
||||
Authentication,
|
||||
Document,
|
||||
User,
|
||||
@@ -25,7 +27,14 @@ router.post("hooks.unfurl", async (ctx) => {
|
||||
}
|
||||
|
||||
const user = await User.findOne({
|
||||
where: { service: "slack", serviceId: event.user },
|
||||
include: [
|
||||
{
|
||||
where: { providerId: event.user },
|
||||
model: UserAuthentication,
|
||||
as: "authentications",
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
if (!user) return;
|
||||
|
||||
@@ -70,11 +79,21 @@ router.post("hooks.interactive", async (ctx) => {
|
||||
throw new AuthenticationError("Invalid verification token");
|
||||
}
|
||||
|
||||
const team = await Team.findOne({
|
||||
where: { slackId: data.team.id },
|
||||
const authProvider = await AuthenticationProvider.findOne({
|
||||
where: {
|
||||
name: "slack",
|
||||
providerId: data.team.id,
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: Team,
|
||||
as: "team",
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
if (!authProvider) {
|
||||
ctx.body = {
|
||||
text:
|
||||
"Sorry, we couldn’t find an integration for your team. Head to your Outline settings to set one up.",
|
||||
@@ -84,6 +103,8 @@ router.post("hooks.interactive", async (ctx) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const { team } = authProvider;
|
||||
|
||||
// we find the document based on the users teamId to ensure access
|
||||
const document = await Document.findOne({
|
||||
where: {
|
||||
@@ -131,20 +152,41 @@ router.post("hooks.slack", async (ctx) => {
|
||||
return;
|
||||
}
|
||||
|
||||
let user;
|
||||
let user, team;
|
||||
|
||||
// attempt to find the corresponding team for this request based on the team_id
|
||||
let team = await Team.findOne({
|
||||
where: { slackId: team_id },
|
||||
});
|
||||
if (team) {
|
||||
user = await User.findOne({
|
||||
where: {
|
||||
teamId: team.id,
|
||||
service: "slack",
|
||||
serviceId: user_id,
|
||||
team = await Team.findOne({
|
||||
include: [
|
||||
{
|
||||
where: {
|
||||
name: "slack",
|
||||
providerId: team_id,
|
||||
},
|
||||
as: "authenticationProviders",
|
||||
model: AuthenticationProvider,
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (team) {
|
||||
const authentication = await UserAuthentication.findOne({
|
||||
where: {
|
||||
providerId: user_id,
|
||||
},
|
||||
include: [
|
||||
{
|
||||
where: { teamId: team.id },
|
||||
model: User,
|
||||
as: "user",
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (authentication) {
|
||||
user = authentication.user;
|
||||
}
|
||||
} else {
|
||||
// If we couldn't find a team it's still possible that the request is from
|
||||
// a team that authenticated with a different service, but connected Slack
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("#hooks.unfurl", () => {
|
||||
event: {
|
||||
type: "link_shared",
|
||||
channel: "Cxxxxxx",
|
||||
user: user.serviceId,
|
||||
user: user.authentications[0].providerId,
|
||||
message_ts: "123456789.9875",
|
||||
links: [
|
||||
{
|
||||
@@ -56,8 +56,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "dsfkndfskndsfkn",
|
||||
},
|
||||
});
|
||||
@@ -76,8 +76,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
},
|
||||
});
|
||||
@@ -98,8 +98,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "*contains",
|
||||
},
|
||||
});
|
||||
@@ -118,8 +118,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
},
|
||||
});
|
||||
@@ -137,8 +137,8 @@ describe("#hooks.slack", () => {
|
||||
await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
},
|
||||
});
|
||||
@@ -161,8 +161,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "help",
|
||||
},
|
||||
});
|
||||
@@ -176,8 +176,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.serviceId,
|
||||
team_id: team.slackId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "",
|
||||
},
|
||||
});
|
||||
@@ -206,7 +206,7 @@ describe("#hooks.slack", () => {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: "unknown-slack-user-id",
|
||||
team_id: team.slackId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
},
|
||||
});
|
||||
@@ -260,8 +260,8 @@ describe("#hooks.slack", () => {
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: "wrong-verification-token",
|
||||
team_id: team.slackId,
|
||||
user_id: user.serviceId,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "Welcome",
|
||||
},
|
||||
});
|
||||
@@ -280,8 +280,8 @@ describe("#hooks.interactive", () => {
|
||||
|
||||
const payload = JSON.stringify({
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user: { id: user.serviceId },
|
||||
team: { id: team.slackId },
|
||||
user: { id: user.authentications[0].providerId },
|
||||
team: { id: team.authenticationProviders[0].providerId },
|
||||
callback_id: document.id,
|
||||
});
|
||||
const res = await server.post("/api/hooks.interactive", {
|
||||
@@ -305,7 +305,7 @@ describe("#hooks.interactive", () => {
|
||||
const payload = JSON.stringify({
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user: { id: "unknown-slack-user-id" },
|
||||
team: { id: team.slackId },
|
||||
team: { id: team.authenticationProviders[0].providerId },
|
||||
callback_id: document.id,
|
||||
});
|
||||
const res = await server.post("/api/hooks.interactive", {
|
||||
@@ -322,7 +322,7 @@ describe("#hooks.interactive", () => {
|
||||
const { user } = await seed();
|
||||
const payload = JSON.stringify({
|
||||
token: "wrong-verification-token",
|
||||
user: { id: user.serviceId, name: user.name },
|
||||
user: { id: user.authentications[0].providerId, name: user.name },
|
||||
callback_id: "doesnt-matter",
|
||||
});
|
||||
const res = await server.post("/api/hooks.interactive", {
|
||||
|
||||
Reference in New Issue
Block a user