-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
doesn't work/build, contains things other than mx, I just want to get this off my laptop
- Loading branch information
lillian
committed
Feb 2, 2024
1 parent
9209141
commit 794585a
Showing
34 changed files
with
1,455 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
module.exports.findCustomer = async ({name, email}) => { | ||
console.log("looking for customer", name, email) | ||
|
||
let res = await fetch("https://api.helcim.com/v2/customers/", { | ||
headers: { "api-token": process.env.NEW_TOKEN } | ||
}); | ||
|
||
let customers = await res.json(); | ||
// console.log(customers); | ||
|
||
let customerByEmail = !!email ? customers.find(c => c.billingAddress?.email === email || c.shippingAddress?.email === email) : null; | ||
let customerByName = !!name ? customers.find(c => c.contactName === name || c.billingAddress?.name === name || c.shippingAddress?.name === name) : null; | ||
|
||
if (!customerByEmail && !customerByName) { | ||
console.log("could not find customer!"); | ||
return null; | ||
} | ||
|
||
if (!customerByEmail) return customerByName; | ||
if (!customerByName) return customerByEmail; | ||
|
||
if (customerByEmail.customerCode != customerByName.customerCode) { | ||
throw { userVisibleError: "Matched different customers by name and email!" }; | ||
} | ||
|
||
return customerByEmail; | ||
} | ||
|
||
const { XMLParser } = require("fast-xml-parser"); | ||
|
||
module.exports.findSubscription = async (customerID) => { | ||
console.log("querying subscriptions for customer " + customerID); | ||
|
||
let res = await fetch("https://secure.myhelcim.com/api/recurring/subscription-search", { | ||
method: "POST", | ||
body: `customerCode=${customerID}`, | ||
headers: { | ||
"account-id": process.env.ACCOUNT_ID, | ||
"api-token": "thisdoesntmatter", | ||
"content-type": "application/x-www-form-urlencoded", | ||
} | ||
}); | ||
|
||
let xml = await res.text(); | ||
|
||
const parsert = new XMLParser(); | ||
let unxmled = parsert.parse(xml)?.subscriptions?.subscription; | ||
|
||
console.log(unxmled); | ||
|
||
console.log(typeof unxmled) | ||
|
||
if (Array.isArray(unxmled)) { | ||
return unxmled.find(s => s.recurringPlanCode === "member1st" && s.status === "Active"); | ||
} | ||
|
||
if (typeof unxmled === 'object') { | ||
if (unxmled.recurringPlanCode === "member1st" && unxmled.status === "Active") { | ||
return unxmled; | ||
} | ||
return null; | ||
} | ||
|
||
if (!unxmled) return null; | ||
|
||
console.log(unxmled); | ||
throw 'unknown unxmled type'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
require("dotenv").config(); | ||
|
||
const http = require("http"); | ||
|
||
const { findCustomer, findSubscription } = require("./helcimapi.js"); | ||
|
||
const getBody = (r) => new Promise(res => { | ||
let data = ''; | ||
r.on('data', (chunk) => data += chunk); | ||
r.on('end', () => res(data)); | ||
}) | ||
|
||
const process = async (data) => { | ||
if (!data.name && !data.email) { | ||
throw { userVisibleError: "must have either 'name' or 'email' in request" }; | ||
} | ||
|
||
let customer = await findCustomer(data); | ||
if (!customer) return [200, { ok: false }]; //throw { userVisibleError: "Customer record not found" }; | ||
console.log("found customer", customer); | ||
|
||
let subscription = await findSubscription(customer.customerCode); | ||
console.log("found subscription?", subscription); | ||
return [200, { ok: !!subscription }] | ||
} | ||
|
||
const handler = async (req, res) => { | ||
console.log(req.method, req.url, req.headers); | ||
let data = await getBody(req); | ||
|
||
if (!data) return; | ||
try { | ||
data = JSON.parse(data); | ||
} catch (e) { | ||
console.error(e); | ||
res.statusCode = 400; | ||
res.end(); | ||
return; | ||
} | ||
|
||
console.log("d", data); | ||
|
||
let status, body; | ||
|
||
try { | ||
[status, body] = await process(data); | ||
} catch(e) { | ||
if (e?.userVisibleError) { | ||
status = 400; | ||
body = { error: e.userVisibleError }; | ||
} else { | ||
console.error(e); | ||
status = 500; | ||
body = {"error": "500 internal server error"} | ||
} | ||
} | ||
|
||
res.statusCode = status; | ||
res.write(JSON.stringify(body)); | ||
res.end(); | ||
}; | ||
|
||
http.createServer(handler).listen(8080, "0.0.0.0") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"dependencies": { | ||
"dotenv": "^16.3.1", | ||
"fast-xml-parser": "^4.3.2" | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package main | ||
|
||
// maybe listadm package idk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"members-platform/internal/db" | ||
|
||
"github.com/emersion/go-smtp" | ||
) | ||
|
||
func main() { | ||
if err := db.ConnectRedis(); err != nil { | ||
log.Fatalln(fmt.Errorf("connect redis: %w", err)) | ||
} | ||
|
||
s := smtp.NewServer(&recvBackend{}) | ||
|
||
s.Addr = "100.80.182.53:2525" | ||
s.Domain = "lists.hacklab.to" | ||
|
||
log.Println("Starting SMTP server at", s.Addr) | ||
log.Fatal(s.ListenAndServe()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
|
||
"github.com/emersion/go-message" | ||
"github.com/emersion/go-smtp" | ||
|
||
jobs "members-platform/internal/jobs" | ||
) | ||
|
||
type recvBackend struct{} | ||
|
||
func (recvBackend) NewSession(c *smtp.Conn) (smtp.Session, error) { | ||
return &session{rcpt: []string{}}, nil | ||
} | ||
|
||
type session struct { | ||
mailfrom string | ||
rcpt []string | ||
} | ||
|
||
// todo: clear session | ||
func (s *session) Reset() {} | ||
|
||
func (s *session) AuthPlain(username, password string) error { | ||
return smtp.ErrAuthUnsupported | ||
} | ||
|
||
func (s *session) Mail(from string, opts *smtp.MailOptions) error { | ||
s.mailfrom = from | ||
return nil | ||
} | ||
|
||
func (s *session) Rcpt(to string, opts *smtp.RcptOptions) error { | ||
s.rcpt = append(s.rcpt, to) | ||
return nil | ||
} | ||
|
||
func (s *session) Data(r io.Reader) error { | ||
data, err := io.ReadAll(r) | ||
if err != nil { | ||
return fmt.Errorf("failed to read email data: %w", err) | ||
} | ||
|
||
_, err = message.Read(bytes.NewReader(data)) | ||
if err != nil { | ||
return fmt.Errorf("parse message: %w", err) | ||
} | ||
|
||
return jobs.EnqueueJob(jobs.JOB_MX_INBOUND, jobs.MxInboundJobData{ | ||
MailFrom: s.mailfrom, | ||
Rcpt: s.rcpt, | ||
Data: data, | ||
}) | ||
} | ||
|
||
func (s *session) Logout() error { | ||
return smtp.ErrAuthUnsupported | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,7 @@ type Confirmation struct { | |
Title string | ||
Message template.HTML | ||
} | ||
|
||
type ApplyData struct { | ||
Error string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,68 @@ | ||
{{ if IsLoggedOut .Ctx.AuthLevel }} | ||
<form class="w-full max-w-sm" hx-post="/apply/" method="post"> | ||
<h2 class="text-xl">Membership Application</h2> | ||
<br> | ||
<input type="hidden" name="type" value="login" /> | ||
Enter the password to apply: | ||
<div class="md:flex md:items-center mb-6"> | ||
<div class="md:w-2/3"> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-password" type="password" name="password"> | ||
</div> | ||
</div> | ||
<button class="shadow bg-blue-500 hover:bg-blue-400 focus:shadow-outline focus:outline-none text-white font-bold py-2 px-4 rounded" type="submit"> | ||
Log in | ||
</button> | ||
{{ if .Data }} | ||
{{ if .Data.Error }} | ||
<p class="text-red-500">Error: {{ .Data.Error }}</p> | ||
{{ end }} | ||
{{ end }} | ||
</form> | ||
{{ else if IsMemberLoggedIn .Ctx.AuthLevel }} | ||
<h2 class="text-xl">Membership Application</h2> | ||
<br> | ||
<p>You are already a member!</p> | ||
{{ else }} | ||
<!-- todo: ask for APPLY_PASSWORD env variable, add to session --> | ||
<p>TODO: put form here</p> | ||
<form> | ||
<h2 class="text-xl">Membership Application</h2> | ||
<div class="columns-2xs"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Preferred Full Name | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Username | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Nickname | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Contact Email address | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Mailing List Email address | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
</div> | ||
<br> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Why do you want to join Hacklab? | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
<br> | ||
<div class="columns-2xs"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Name of first sponsoring member | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
<label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-full-name"> | ||
Name of second sponsoring member | ||
</label> | ||
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white" id="inline-full-name" type="text" name="username"> | ||
</div> | ||
</form> | ||
{{ end }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.