Merge pull request #394 from Irev-Dev/main
Release 1st July 2021
This commit was merged in pull request #394.
This commit is contained in:
@@ -1,16 +1,10 @@
|
|||||||
services:
|
services:
|
||||||
|
|
||||||
openscad-health:
|
openscad-preview:
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: ./openscad/Dockerfile
|
dockerfile: ./openscad/Dockerfile
|
||||||
image: openscad
|
image: openscad
|
||||||
command: openscad.health
|
|
||||||
ports:
|
|
||||||
- "5051:8080"
|
|
||||||
|
|
||||||
openscad-preview:
|
|
||||||
image: openscad
|
|
||||||
command: openscad.preview
|
command: openscad.preview
|
||||||
ports:
|
ports:
|
||||||
- "5052:8080"
|
- "5052:8080"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ ARG DEBIAN_FRONTEND=noninteractive
|
|||||||
RUN apt-get update -qq
|
RUN apt-get update -qq
|
||||||
# double check this below, I'm not sure we need inkscape etc
|
# double check this below, I'm not sure we need inkscape etc
|
||||||
RUN apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb imagemagick unzip inkscape
|
RUN apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb imagemagick unzip inkscape
|
||||||
|
RUN add-apt-repository ppa:openscad/releases
|
||||||
RUN apt-get update -qq
|
RUN apt-get update -qq
|
||||||
RUN apt-get install -y -qq openscad
|
RUN apt-get install -y -qq openscad
|
||||||
RUN apt-get install -y curl wget
|
RUN apt-get install -y curl wget
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ export const schema = gql`
|
|||||||
type EmailResponse {
|
type EmailResponse {
|
||||||
accepted: [String!]!
|
accepted: [String!]!
|
||||||
rejected: [String!]!
|
rejected: [String!]!
|
||||||
messageId: String!
|
|
||||||
envelope: Envelope
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input Email {
|
input Email {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import nodemailer, { SendMailOptions } from 'nodemailer'
|
import nodemailer, { SendMailOptions } from 'nodemailer'
|
||||||
|
|
||||||
interface Args {
|
export interface SendMailArgs {
|
||||||
to: SendMailOptions['to']
|
to: string
|
||||||
from: SendMailOptions['from']
|
from: SendMailOptions['from']
|
||||||
subject: string
|
subject: string
|
||||||
text: string
|
text: string
|
||||||
@@ -26,7 +26,7 @@ export function sendMail({
|
|||||||
from,
|
from,
|
||||||
subject,
|
subject,
|
||||||
text,
|
text,
|
||||||
}: Args): Promise<SuccessResult> {
|
}: SendMailArgs): Promise<SuccessResult> {
|
||||||
const transporter = nodemailer.createTransport({
|
const transporter = nodemailer.createTransport({
|
||||||
host: 'smtp.mailgun.org',
|
host: 'smtp.mailgun.org',
|
||||||
port: 587,
|
port: 587,
|
||||||
|
|||||||
@@ -1,26 +1,45 @@
|
|||||||
import { requireAuth } from 'src/lib/auth'
|
import { requireAuth } from 'src/lib/auth'
|
||||||
import { sendMail } from 'src/lib/sendmail'
|
import { sendMail } from 'src/lib/sendmail'
|
||||||
|
import type { SendMailArgs } from 'src/lib/sendmail'
|
||||||
import { users } from 'src/services/users/users'
|
import { users } from 'src/services/users/users'
|
||||||
|
|
||||||
export const sendAllUsersEmail = async ({ input: { body, subject } }) => {
|
export const sendAllUsersEmail = async ({ input: { body, subject } }) => {
|
||||||
requireAuth({ role: 'admin' })
|
requireAuth({ role: 'admin' })
|
||||||
const recipients = (await users()).map(({ email }) => email)
|
|
||||||
const from = {
|
const from = {
|
||||||
address: 'news@mail.cadhub.xyz',
|
address: 'news@mail.cadhub.xyz',
|
||||||
name: 'CadHub',
|
name: 'CadHub',
|
||||||
}
|
}
|
||||||
const result = await sendMail({
|
const emails: SendMailArgs[] = (await users()).map(({ email }) => ({
|
||||||
to: recipients,
|
to: email,
|
||||||
from,
|
from,
|
||||||
subject,
|
subject,
|
||||||
text: body,
|
text: body,
|
||||||
|
}))
|
||||||
|
const emailPromises = emails.map((email) => sendMail(email))
|
||||||
|
const accepted = []
|
||||||
|
const rejected = []
|
||||||
|
const result = await Promise.allSettled(emailPromises)
|
||||||
|
result.forEach((result) => {
|
||||||
|
if (result.status === 'fulfilled') {
|
||||||
|
accepted.push(result.value.accepted[0])
|
||||||
|
} else {
|
||||||
|
rejected.push(result.reason)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
await sendMail({
|
await sendMail({
|
||||||
to: 'k.hutten@protonmail.ch',
|
to: 'k.hutten@protonmail.ch',
|
||||||
from,
|
from,
|
||||||
subject: `All users email report`,
|
subject: `All users email report`,
|
||||||
text: JSON.stringify(result, null, 2),
|
text: JSON.stringify(
|
||||||
|
{
|
||||||
|
accepted,
|
||||||
|
rejected,
|
||||||
|
originalEmailList: emails,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
})
|
})
|
||||||
|
|
||||||
return result
|
return { accepted, rejected }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Link, routes } from '@redwoodjs/router'
|
|||||||
import { QUERY } from 'src/components/AdminPartsCell'
|
import { QUERY } from 'src/components/AdminPartsCell'
|
||||||
|
|
||||||
const DELETE_PART_MUTATION = gql`
|
const DELETE_PART_MUTATION = gql`
|
||||||
mutation DeletePartMutation($id: String!) {
|
mutation DeletePartMutationAdmin($id: String!) {
|
||||||
deletePart(id: $id) {
|
deletePart(id: $id) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Link, routes } from '@redwoodjs/router'
|
|||||||
import AdminParts from 'src/components/AdminParts'
|
import AdminParts from 'src/components/AdminParts'
|
||||||
|
|
||||||
export const QUERY = gql`
|
export const QUERY = gql`
|
||||||
query PARTS {
|
query PARTS_ADMIN {
|
||||||
parts {
|
parts {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { navigate, routes } from '@redwoodjs/router'
|
|||||||
import UserProfile from 'src/components/UserProfile'
|
import UserProfile from 'src/components/UserProfile'
|
||||||
|
|
||||||
export const QUERY = gql`
|
export const QUERY = gql`
|
||||||
query FIND_USER_BY_ID($userName: String!) {
|
query FIND_USER_BY_USERNAME($userName: String!) {
|
||||||
user: userName(userName: $userName) {
|
user: userName(userName: $userName) {
|
||||||
id
|
id
|
||||||
userName
|
userName
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ const Footer = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="bg-indigo-900 text-indigo-200 font-roboto mt-20 text-sm">
|
<div className="bg-indigo-900 text-indigo-200 font-roboto mt-20 text-sm">
|
||||||
<div className="flex h-16 justify-end items-center mx-16">
|
<div className="flex h-16 justify-end items-center mx-16">
|
||||||
|
<OutBound className="mr-8" to="https://github.com/Irev-Dev/cadhub">
|
||||||
|
Github
|
||||||
|
</OutBound>
|
||||||
<OutBound className="mr-8" to="https://learn.cadhub.xyz/">
|
<OutBound className="mr-8" to="https://learn.cadhub.xyz/">
|
||||||
Docs
|
Docs
|
||||||
</OutBound>
|
</OutBound>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const QUERY = gql`
|
|||||||
`
|
`
|
||||||
|
|
||||||
const UPDATE_PART_MUTATION = gql`
|
const UPDATE_PART_MUTATION = gql`
|
||||||
mutation UpdatePartMutation($id: String!, $input: UpdatePartInput!) {
|
mutation UpdatePartMutationIde($id: String!, $input: UpdatePartInput!) {
|
||||||
updatePart(id: $id, input: $input) {
|
updatePart(id: $id, input: $input) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ const LandingSection = () => {
|
|||||||
ode is the future of <span className="text-6xl">C</span>
|
ode is the future of <span className="text-6xl">C</span>
|
||||||
AD
|
AD
|
||||||
</h1>
|
</h1>
|
||||||
<div className="text-indigo-600 text-base font-normal self-end pt-3 tracking-widest">
|
<div className="text-indigo-600 text-base font-normal self-end pt-3 tracking-widest max-w-2xl"></div>
|
||||||
No more click-n-drool.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user