diff --git a/PROJECTS/beginner/canary-token-generator/backend/cmd/builddocxtemplate/main.go b/PROJECTS/beginner/canary-token-generator/backend/cmd/builddocxtemplate/main.go new file mode 100644 index 00000000..5bfbba1d --- /dev/null +++ b/PROJECTS/beginner/canary-token-generator/backend/cmd/builddocxtemplate/main.go @@ -0,0 +1,127 @@ +// ©AngelaMos | 2026 +// main.go + +package main + +import ( + "archive/zip" + "flag" + "fmt" + "log" + "os" + "path/filepath" +) + +const ( + contentTypesXML = ` + + + + + + +` + + packageRelsXML = ` + + + +` + + documentXML = ` + + + Internal document - confidential. Do not redistribute. + + + + + + + +` + + documentRelsXML = ` + + + +` + + footer2XML = ` + + + + INCLUDEPICTURE "HONEY_TRACK_URL" \d \* MERGEFORMAT + + + +` + + pathContentTypes = "[Content_Types].xml" + pathPackageRels = "_rels/.rels" + pathDocument = "word/document.xml" + pathDocumentRels = "word/_rels/document.xml.rels" + pathFooter2 = "word/footer2.xml" + + dirPerm os.FileMode = 0o755 + filePerm os.FileMode = 0o644 +) + +type entry struct { + name string + body string + method uint16 +} + +func entries() []entry { + return []entry{ + {name: pathContentTypes, body: contentTypesXML, method: zip.Store}, + {name: pathPackageRels, body: packageRelsXML, method: zip.Deflate}, + {name: pathDocument, body: documentXML, method: zip.Deflate}, + {name: pathDocumentRels, body: documentRelsXML, method: zip.Store}, + {name: pathFooter2, body: footer2XML, method: zip.Deflate}, + } +} + +func main() { + out := flag.String("out", "", "output path for template.docx") + flag.Parse() + + if *out == "" { + log.Fatal("usage: builddocxtemplate -out ") + } + + if err := buildTemplate(*out); err != nil { + log.Fatalf("build docx template: %v", err) + } + + fmt.Printf("wrote %s\n", *out) +} + +func buildTemplate(out string) error { + if err := os.MkdirAll(filepath.Dir(out), dirPerm); err != nil { + return fmt.Errorf("mkdir parent: %w", err) + } + + f, err := os.OpenFile(out, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, filePerm) + if err != nil { + return fmt.Errorf("open output: %w", err) + } + defer f.Close() + + w := zip.NewWriter(f) + for _, e := range entries() { + hdr := &zip.FileHeader{Name: e.name, Method: e.method} + fw, cErr := w.CreateHeader(hdr) + if cErr != nil { + return fmt.Errorf("create %s: %w", e.name, cErr) + } + if _, wErr := fw.Write([]byte(e.body)); wErr != nil { + return fmt.Errorf("write %s: %w", e.name, wErr) + } + } + if err := w.Close(); err != nil { + return fmt.Errorf("close zip writer: %w", err) + } + return nil +} diff --git a/PROJECTS/beginner/canary-token-generator/backend/internal/token/generators/docx/template/template.docx b/PROJECTS/beginner/canary-token-generator/backend/internal/token/generators/docx/template/template.docx new file mode 100644 index 00000000..be7405d1 Binary files /dev/null and b/PROJECTS/beginner/canary-token-generator/backend/internal/token/generators/docx/template/template.docx differ