Whatsapp send and Zammad autologin fixes

This commit is contained in:
Darren Clarke 2023-09-08 16:34:13 +02:00
parent a3d6b786e1
commit 9e68be7225
15 changed files with 153 additions and 100 deletions

View file

@ -146,7 +146,7 @@ export const Login: FC<LoginProps> = ({ session }) => {
sx={buttonStyles}
onClick={() =>
signIn("google", {
callbackUrl: `${origin}/setup`,
callbackUrl: `${origin}`,
})
}
>
@ -160,7 +160,7 @@ export const Login: FC<LoginProps> = ({ session }) => {
sx={buttonStyles}
onClick={() =>
signIn("apple", {
callbackUrl: `${window.location.origin}/setup`,
callbackUrl: `${window.location.origin}`,
})
}
>

View file

@ -3,4 +3,4 @@
import { FC } from "react";
import { ZammadWrapper } from "./ZammadWrapper";
export const Home: FC = () => <ZammadWrapper path="/#dashboard" hideSidebar />;
export const Home: FC = () => <ZammadWrapper path="#dashboard" hideSidebar />;

View file

@ -1,8 +1,10 @@
"use client";
import { FC, useState } from "react";
import { FC, useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import Iframe from "react-iframe";
import { useSession } from "next-auth/react";
import { Box, Grid, CircularProgress } from "@mui/material";
type ZammadWrapperProps = {
path: string;
@ -14,69 +16,117 @@ export const ZammadWrapper: FC<ZammadWrapperProps> = ({
hideSidebar = true,
}) => {
const router = useRouter();
const { data: session } = useSession();
const [authenticated, setAuthenticated] = useState(false);
const [display, setDisplay] = useState("none");
const url = `/zammad${path}`;
const id = url.replace(/[^a-zA-Z0-9]/g, "");
return (
// @ts-ignore
<Iframe
id="zammad"
url={url}
width="100%"
height="100%"
frameBorder={0}
styles={{ display }}
onLoad={() => {
const linkElement = document.querySelector("iframe");
if (
linkElement.contentDocument &&
linkElement.contentDocument?.querySelector &&
linkElement.contentDocument.querySelector("#navigation") &&
linkElement.contentDocument.querySelector("body")
) {
// @ts-ignore
linkElement.contentDocument.querySelector("#navigation").style =
"display: none";
// @ts-ignore
linkElement.contentDocument.querySelector("body").style =
"font-family: Arial";
useEffect(() => {
const checkAuthenticated = async () => {
const res = await fetch("/zammad/auth/sso", {
method: "GET",
redirect: "manual",
});
if (res.type === "opaqueredirect") {
setAuthenticated(true);
} else {
setAuthenticated(false);
}
};
checkAuthenticated();
}, [path]);
if (!session) {
console.log("No session");
return (
<Box sx={{ width: "100%" }}>
<Grid
container
direction="column"
sx={{ height: 500 }}
justifyContent="center"
alignContent="center"
alignItems="center"
>
<Grid item>
<CircularProgress size={80} color="success" />
</Grid>
</Grid>
</Box>
);
}
if (session && authenticated) {
console.log("Session and authenticated");
return (
<Iframe
id={id}
url={url}
width="100%"
height="100%"
frameBorder={0}
styles={{ display }}
onLoad={() => {
const linkElement = document.querySelector(
`#${id}`,
) as HTMLIFrameElement;
console.log({ path });
console.log({ id });
console.log({ linkElement });
if (
hideSidebar &&
linkElement.contentDocument.querySelector(".sidebar")
linkElement.contentDocument &&
linkElement.contentDocument?.querySelector &&
linkElement.contentDocument.querySelector("#navigation") &&
linkElement.contentDocument.querySelector("body")
) {
// @ts-ignore
linkElement.contentDocument.querySelector(".sidebar").style =
linkElement.contentDocument.querySelector("#navigation").style =
"display: none";
}
// @ts-ignore
if (linkElement.contentDocument.querySelector(".overview-header")) {
// @ts-ignore
(
linkElement.contentDocument.querySelector(
".overview-header",
) as any
).style = "display: none";
}
linkElement.contentDocument.querySelector("body").style =
"font-family: Arial";
setDisplay("inherit");
if (
hideSidebar &&
linkElement.contentDocument.querySelector(".sidebar")
) {
// @ts-ignore
linkElement.contentDocument.querySelector(".sidebar").style =
"display: none";
}
if (linkElement.contentWindow) {
linkElement.contentWindow.addEventListener("hashchange", () => {
const hash = linkElement.contentWindow?.location?.hash ?? "";
if (hash.startsWith("#ticket/zoom/")) {
setDisplay("none");
const ticketID = hash.split("/").pop();
router.push(`/tickets/${ticketID}`);
setTimeout(() => {
setDisplay("inherit");
}, 1000);
}
});
// @ts-ignore
if (linkElement.contentDocument.querySelector(".overview-header")) {
// @ts-ignore
(
linkElement.contentDocument.querySelector(
".overview-header",
) as any
).style = "display: none";
}
setDisplay("inherit");
if (linkElement.contentWindow) {
linkElement.contentWindow.addEventListener("hashchange", () => {
const hash = linkElement.contentWindow?.location?.hash ?? "";
if (hash.startsWith("#ticket/zoom/")) {
setDisplay("none");
const ticketID = hash.split("/").pop();
router.push(`/tickets/${ticketID}`);
setTimeout(() => {
setDisplay("inherit");
}, 1000);
}
});
}
}
}
}}
/>
);
}}
/>
);
}
};

View file

@ -22,20 +22,21 @@ const checkRewrites = async (request: NextRequestWithAuth) => {
const metamigoURL = process.env.METAMIGO_URL ?? "http://metamigo-api:3000";
const labelStudioURL = process.env.LABEL_STUDIO_URL ?? "http://label-studio:8080";
const { token } = request.nextauth;
const headers = { 'X-Forwarded-User': token?.email?.toLowerCase() };
console.log(request.nextUrl);
if (request.nextUrl.pathname.startsWith('/metamigo')) {
return rewriteURL(request, `${linkBaseURL}/metamigo`, metamigoURL);
} else if (request.nextUrl.pathname.startsWith('/label-studio')) {
return rewriteURL(request, `${linkBaseURL}/label-studio`, labelStudioURL);
} else if (request.nextUrl.pathname.startsWith('/zammad')) {
return rewriteURL(request, `${linkBaseURL}/zammad`, zammadURL);
return rewriteURL(request, `${linkBaseURL}/zammad`, zammadURL, headers);
} else if (request.nextUrl.pathname.startsWith('/auth/sso') || request.nextUrl.pathname.startsWith('/assets')) {
const headers = { 'X-Forwarded-User': token.email.toLowerCase() };
return rewriteURL(request, linkBaseURL, zammadURL, headers);
} else if (request.nextUrl.pathname.startsWith('/proxy/api') || request.nextUrl.pathname.startsWith('/proxy/assets')) {
return rewriteURL(request, `${linkBaseURL}/proxy`, zammadURL);
} else if (request.nextUrl.pathname.startsWith('/api/v1') || request.nextUrl.pathname.startsWith('/auth/sso')) {
return rewriteURL(request, linkBaseURL, zammadURL);
return rewriteURL(request, linkBaseURL, zammadURL, headers);
}
return NextResponse.next();
@ -75,7 +76,7 @@ export default withAuth(
export const config = {
matcher: [
'/((?!ws|_next/static|_next/image|favicon.ico).*)',
'/((?!ws|wss|_next/static|_next/image|favicon.ico).*)',
],
};

View file

@ -10,17 +10,17 @@ USER root
RUN set -ex; \
apt-get update; \
apt-get install -y --no-install-recommends nodejs git libclang-dev clang llvm pkg-config nettle-dev;
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ARG SEQUOIA_PROJECT_URL=https://gitlab.com/sequoia-pgp/sequoia-ffi.git
ARG SEQUOIA_GIT_TAG=main
ENV SEQUOIA_DIR=/usr/lib/sequoia
ENV LD_LIBRARY_PATH=${SEQUOIA_DIR}/target/debug
RUN git clone -b "${SEQUOIA_GIT_TAG}" --single-branch --depth 1 "${SEQUOIA_PROJECT_URL}" "${SEQUOIA_DIR}";
WORKDIR ${SEQUOIA_DIR}
RUN export PATH=~/.cargo/bin:$PATH && cargo build -p sequoia-openpgp-ffi;
# RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
# ARG SEQUOIA_PROJECT_URL=https://gitlab.com/sequoia-pgp/sequoia-ffi.git
# ARG SEQUOIA_GIT_TAG=main
# ENV SEQUOIA_DIR=/usr/lib/sequoia
# ENV LD_LIBRARY_PATH=${SEQUOIA_DIR}/target/debug
# RUN git clone -b "${SEQUOIA_GIT_TAG}" --single-branch --depth 1 "${SEQUOIA_PROJECT_URL}" "${SEQUOIA_DIR}";
# WORKDIR ${SEQUOIA_DIR}
# RUN export PATH=~/.cargo/bin:$PATH && cargo build -p sequoia-openpgp-ffi;
WORKDIR ${ZAMMAD_DIR}
RUN echo "gem 'ruby_openpgp', git: 'https://github.com/throneless-tech/ruby_openpgp', branch: 'signing-and-userids'" >> Gemfile.local
# RUN echo "gem 'ruby_openpgp', git: 'https://github.com/throneless-tech/ruby_openpgp', branch: 'signing-and-userids'" >> Gemfile.local
RUN bundle install --without test development mysql
RUN sed -i '/^[[:space:]]*# create install ready file/ i\
echo "about to reinstall..."\n\
@ -34,8 +34,8 @@ FROM node:16.18.0-slim as node
FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION}
USER ${ZAMMAD_USER}
ENV SEQUOIA_DIR=/usr/lib/sequoia
ENV LD_LIBRARY_PATH=${SEQUOIA_DIR}/target/debug
# ENV SEQUOIA_DIR=/usr/lib/sequoia
# ENV LD_LIBRARY_PATH=${SEQUOIA_DIR}/target/debug
ENV ZAMMAD_READY_FILE=${ZAMMAD_DIR}/var/zammad.ready
COPY --from=node /opt /opt
COPY --from=node /usr/local/bin /usr/local/bin

View file

@ -1,6 +1,6 @@
{
"name": "link-stack",
"version": "2.0.0b2",
"version": "2.0.0b3",
"description": "",
"main": "index.js",
"scripts": {

View file

@ -1,8 +1,6 @@
# frozen_string_literal: true
class Channel
class Driver
class CdrWhatsapp
class Channel::Driver::CdrWhatsapp
def fetchable?(_channel)
false
end
@ -50,6 +48,4 @@ class Channel
end
options
end
end
end
end

View file

@ -29,3 +29,4 @@ module Ticket::Article::EnqueueCommunicateCdrSignalJob
CommunicateCdrSignalJob.perform_later(id)
end
end

View file

@ -24,8 +24,9 @@ module Ticket::Article::EnqueueCommunicateCdrWhatsappJob
return true unless type_id
type = Ticket::Article::Type.lookup(id: type_id)
return true unless type.name.match?(/\Acdr_whatspp/i)
return true unless type.name.match?(/\Acdr_whatsapp/i)
CommunicateCdrWhatsappJob.perform_later(id)
end
end

View file

@ -1,7 +1,9 @@
# frozen_string_literal: true
Rails.application.config.after_initialize do
# Ticket::Article.add_observer Observer::Ticket::Article::CommunicateCdrSignal.instance
class Ticket::Article
include Ticket::Article::EnqueueCommunicateCdrSignalJob
end
icon = File.read('public/assets/images/icons/cdr_signal.svg')
doc = File.open('public/assets/images/icons.svg') { |f| Nokogiri::XML(f) }
@ -13,3 +15,4 @@ Rails.application.config.after_initialize do
end
File.write('public/assets/images/icons.svg', doc.to_xml)
end

View file

@ -1,7 +1,10 @@
# frozen_string_literal: true
Rails.application.config.after_initialize do
# Ticket::Article.add_observer Observer::Ticket::Article::CommunicateCdrWhatsapp.instance
class Ticket::Article
include Ticket::Article::EnqueueCommunicateCdrWhatsappJob
end
icon = File.read('public/assets/images/icons/cdr_whatsapp.svg')
doc = File.open('public/assets/images/icons.svg') { |f| Nokogiri::XML(f) }

View file

@ -12,7 +12,7 @@ class CdrSignal
#
def self.check_token(api_url, token)
api = CdrSignalAPI.new(api_url, token)
api = CdrSignalApi.new(api_url, token)
begin
bot = api.fetch_self
rescue StandardError => e
@ -128,7 +128,7 @@ class CdrSignal
def initialize(api_url, token)
@token = token
@api_url = api_url
@api = CdrSignalAPI.new(api_url, token)
@api = CdrSignalApi.new(api_url, token)
end
#

View file

@ -4,13 +4,12 @@ require 'json'
require 'net/http'
require 'net/https'
require 'uri'
require 'rest-client'
class CdrSignalAPI
class CdrSignalApi
def initialize(api_url, token)
@token = token
@last_update = 0
@api = api_url
@api_url = api_url
end
def parse_hash(hash)
@ -22,13 +21,13 @@ class CdrSignalAPI
end
def get(api)
url = "#{@api}/bots/#{@token}/#{api}"
JSON.parse(RestClient.get(url, { accept: :json }).body)
url = "#{@api_url}/bots/#{@token}/#{api}"
JSON.parse(Faraday.get(url, { Accept: "application/json" }).body)
end
def post(api, params = {})
url = "#{@api}/bots/#{@token}/#{api}"
JSON.parse(RestClient.post(url, params, { accept: :json }).body)
url = "#{@api_url}/bots/#{@token}/#{api}"
JSON.parse(Faraday.post(url, params.to_json, { "Content-Type": "application/json", Accept: "application/json" }).body)
end
def fetch_self

View file

@ -12,7 +12,7 @@ class CdrWhatsapp
#
def self.check_token(api_url, token)
api = CdrWhatsappAPI.new(api_url, token)
api = CdrWhatsappApi.new(api_url, token)
begin
bot = api.fetch_self
rescue StandardError => e
@ -128,7 +128,7 @@ class CdrWhatsapp
def initialize(api_url, token)
@token = token
@api_url = api_url
@api = CdrWhatsappAPI.new(api_url, token)
@api = CdrWhatsappApi.new(api_url, token)
end
#

View file

@ -4,9 +4,8 @@ require 'json'
require 'net/http'
require 'net/https'
require 'uri'
require 'rest-client'
class CdrWhatsappAPI
class CdrWhatsappApi
def initialize(api_url, token)
@token = token
@last_update = 0
@ -23,12 +22,12 @@ class CdrWhatsappAPI
def get(api)
url = "#{@api_url}/bots/#{@token}/#{api}"
JSON.parse(RestClient.get(url, { accept: :json }).body)
JSON.parse(Faraday.get(url, { Accept: "application/json" }).body)
end
def post(api, params = {})
url = "#{@api_url}/bots/#{@token}/#{api}"
JSON.parse(RestClient.post(url, params, { accept: :json }).body)
JSON.parse(Faraday.post(url, params.to_json, { "Content-Type": "application/json", Accept: "application/json" }).body)
end
def fetch_self