Eop card browser/m2 eop deck browsing#3181
Conversation
…as in source files
…witch as a default card
…d its children ([version]/[lang])
There was a problem hiding this comment.
Pull request overview
This PR adds support for browsing and rendering the “Elevation of Privilege” (EoP) deck in the SvelteKit website (new edition constant, deck loading, UI toggles, taxonomy/mapping rendering, and i18n strings).
Changes:
- Add
VERSION_EOPand wire EoP (eop,5.0) into deck/suit loading and existing browsing routes. - Extend card-code validation lists and update ordering/color mappings for new EoP suits/cards.
- Introduce EoP-specific UI components (taxonomy + mapping) and extend tests to cover the new deck.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| cornucopia.owasp.org/src/routes/edition/[edition]/+page.svelte | Adds EoP as a selectable edition and renders its description/suits. |
| cornucopia.owasp.org/src/routes/edition/[edition]/[card]/+page.svelte | Extends allowed card IDs to include EoP codes and labels edition name for eop. |
| cornucopia.owasp.org/src/routes/edition/[edition]/[card]/[version]/+page.svelte | Extends allowed card IDs to include EoP codes and labels edition name for eop. |
| cornucopia.owasp.org/src/routes/edition/[edition]/[card]/[version]/[lang]/+page.svelte | Extends allowed card IDs to include EoP codes and labels edition name for eop. |
| cornucopia.owasp.org/src/routes/cards/+page.svelte | Adds EoP suits to the cards browser UI, preview selection, and noscript output. |
| cornucopia.owasp.org/src/routes/cards/+page.server.ts | Loads EoP deck cards server-side and merges into the deck map. |
| cornucopia.owasp.org/src/routes/cards/[card]/+page.svelte | Extends allowed card IDs to include EoP codes and labels edition name for eop. |
| cornucopia.owasp.org/src/routes/cards/[card]/+page.server.ts | Loads EoP deck cards server-side for per-card pages. |
| cornucopia.owasp.org/src/lib/services/decService.integration.test.ts | Updates integration expectations for EoP deck presence and total card counts. |
| cornucopia.owasp.org/src/lib/services/deckServiceConsts.ts | Adds VERSION_EOP. |
| cornucopia.owasp.org/src/lib/services/deckService.ts | Registers EoP deck metadata (latest + available decks). |
| cornucopia.owasp.org/src/lib/services/deckService.test.ts | Adds unit tests for EoP edition/version/language and adjusts deck counts. |
| cornucopia.owasp.org/src/lib/components/eopCardTaxonomy.svelte | New: taxonomy display for EoP cards (mappings + attacks). |
| cornucopia.owasp.org/src/lib/components/eopCardMapping.svelte | New: compact STRIDE mapping renderer for EoP cards in previews. |
| cornucopia.owasp.org/src/lib/components/cardPreview.svelte | Refactors mapping rendering to support EoP mapping component. |
| cornucopia.owasp.org/src/lib/components/cardFound.svelte | Refactors taxonomy rendering to support EoP taxonomy component. |
| cornucopia.owasp.org/src/domain/suit/suitController.ts | Adds EoP deck/language metadata for suit discovery. |
| cornucopia.owasp.org/src/domain/suit/order.ts | Adds suit ordering for STRIDE suit names. |
| cornucopia.owasp.org/src/domain/card/order.ts | Adds per-suit ordering for EoP card IDs. |
| cornucopia.owasp.org/src/domain/card/cardColor.ts | Adds color keys for STRIDE suit names. |
| cornucopia.owasp.org/data/website/phrases/en/cards.json | Adds EoP copy + i18n keys for button/heading and EoP taxonomy headings. |
|
You have the card texts, and the cards are browsable. No styling is applied, but I guess that is what you are working on next? |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Yes, styling is imported from copi. I also linked the EoP cards in the Copi game to their card browser pages, so players can click any card to learn more! |
| const mappingComponents: Record<string, Component<any>> = { | ||
| mobileapp: MobileAppCardMapping, | ||
| companion: CompanionCardMapping, | ||
| eop: EopCardMapping | ||
| }; |
| def update_card_urls(path) do | ||
| case YamlElixir.read_from_file(path) do | ||
| {:ok, cards} -> | ||
| edition = cards["meta"]["edition"] | ||
| language = cards["meta"]["language"] | ||
| version = cards["meta"]["version"] | ||
| for suit <- cards["suits"] do | ||
| for card <- suit["cards"] do | ||
| if Map.has_key?(card, "url") do | ||
| value = to_string(card["value"]) | ||
| existing_card = Repo.get_by(Card, category: suit["name"], value: value, edition: edition, language: language, version: version) | ||
|
|
||
| if existing_card do | ||
| existing_card | ||
| |> Ecto.Changeset.change(url: card["url"]) | ||
| |> Repo.update!() | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end |
| update_card_urls(Path.join(:code.priv_dir(:copi), "/repo/cornucopia/eop-cards-5.0-en.yaml")) | ||
| update_card_urls(Path.join(:code.priv_dir(:copi), "/repo/cornucopia/eop-cards-5.1-en.yaml")) |
| "SPA","SP2","SP3","SP4","SP5","SP6","SP7","SP8","SP9","SPX","SPJ","SPQ","SPK", | ||
| "TAA","TA2","TA3","TA4","TA5","TA6","TA7","TA8","TA9","TAX","TAJ","TAQ","TAK", | ||
| "REA","RE2","RE3","RE4","RE5","RE6","RE7","RE8","RE9","REX","REJ","REQ","REK", | ||
| "IDA","ID2","ID3","ID4","ID5","ID6","ID7","ID8","ID9","IDX","IDJ","IDQ","IDK", | ||
| "DSA","DS2","DS3","DS4","DS5","DS6","DS7","DS8","DS9","DSX","DSJ","DSQ","DSK", |
There was a problem hiding this comment.
A duplicate content here. Worth to separate out.
|
@ayman-art, this is a great start. I would like you to take this a step further. The css for copi.owasp.org was never really in line with the original graphics of the EoP card game. F.ex. We are lacking the numbers in the background on the cards. Which is evident from looking at https://github.com/adamshostack/eop/blob/master/EoP_Card%20Game%20Images.pdf You should more faithfully try to reproduce the design, as it was initially conceived for the physical cards. |
Thanks @sydseter! I'll rework the EoP card styling in this PR to reproduce the original card design as faithfully as possible, focusing on the card sizing and the background numbers that are missing in copi. I'll also keep the CSS structured to make the later customisation work easier. |
| end | ||
|
|
||
|
|
||
| def update_card_urls(path) do |
There was a problem hiding this comment.
What is the intention behind this new migration method?
What are you trying to do?
Tje existing code alteady handles card migrations.
If you need to import the urls you should simply update the version number of the yaml file.
|
|
||
| def change do | ||
| update_card_urls(Path.join(:code.priv_dir(:copi), "/repo/cornucopia/eop-cards-5.0-en.yaml")) | ||
| update_card_urls(Path.join(:code.priv_dir(:copi), "/repo/cornucopia/eop-cards-5.1-en.yaml")) |
There was a problem hiding this comment.
You are importing the cards twice. Once with v5.0 and once with v5.1. It is worth considering what is happening here. Pay attention to the version number in the meta data in the card yaml file. Does the meta -> version have the correct version number? Is it higher than tje existing number that has been used previously?
There was a problem hiding this comment.
You shouldn’t need to import the data twice.
Description
Changes
Feature 1: EoP edition in the Card Browser UI
data/website/phrases/en/cards.json: EoP button, header and descriptionFeature 2: EoP deck and suit registration
Registered eop 5.0/en; suits in source order (SP, TA, RE, ID, DS, EP), starting with Ace like the other editions.
src/lib/services/deckService.ts,deckServiceConsts.ts,src/domain/suit/suitController.tssrc/domain/suit/order.ts,src/domain/card/order.tsFeature 3: Card routes for all 78 EoP cards
SP2 is the default card on version switch (as AAI2 for Companion).
src/routes/cards/+page.server.ts,+page.svelte,src/routes/cards/[card]/…src/routes/edition/[edition]/+page.svelte,edition/[edition]/[card]/…and its[version]/[lang]children (cards_options)Feature 4: EoP card styling imported from copi
Feature 5: STRIDE mappings component
src/lib/components/eopCardMapping.svelte: renders the stride fieldcardPreview.svelte: mappings refactored via a component map so that future editions will require changing one line.Feature 6: Card taxonomy
Threat Modeling template from M1, Mappings and Attacks sections, same structure as Companion.
src/lib/components/eopCardTaxonomy.svelte,cardFound.svelte(same component-map refactor)data/website/phrases/en/cards.json: two translation keysFeature 7: Copi cards link to cornucopia card pages
EoP cards in copi games now show a "Need more info?" link that opens the card's page on cornucopia.owasp.org to help players know more about the card.
priv/repo/cornucopia/eop-cards-5.0-en.yaml,eop-cards-5.1-en.yaml: addedurl: "https://cornucopia.owasp.org/cards/<id>"to all 78 cards in each filelib/copi/migrations/card_migration.ex: addedupdate_card_urls/1, which reads a deck yaml and writes the urls onto cards that are already in the database.priv/repo/migrations/20260711100557_populate_eop_card_urls.exs: new migration to add the urls to cards in database.lib/copi_web/controllers/card_html/show.html.heex: shows the link on EoP cards that have a url, same as companionFeature 8: Tests
deckService.test.ts,decService.integration.test.ts: EoP registration coveredScreenshots:
Notes
vw/clamp()values, so EoP cards define their own size (240–320px) instead of filling their layout slot. That is why EoP cards are smaller than the other editions. Open to editing.Resolved or fixed issue: none (partial progress on #1322)
AI Tool Disclosure
[e.g. GitHub CoPilot, ChatGPT, JetBrains Junie etc.][e.g. GPT-4.1, Claude Haiku 4.5, Gemini 2.5 Pro etc.][Summarize the key prompts or instructions given to the AI tools]Affirmation