Skip to content

Commit 039a107

Browse files
authored
Patchs sécurité javascript (#5517)
1 parent b856022 commit 039a107

3 files changed

Lines changed: 82 additions & 49 deletions

File tree

apps/transport/client/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
"webpack-merge": "^6.0.1"
6363
},
6464
"resolutions": {
65-
"kind-of": "^6.0.3"
65+
"kind-of": "^6.0.3",
66+
"fast-uri": "^3.1.2",
67+
"@babel/plugin-transform-modules-systemjs": "^7.29.4"
6668
}
6769
}

apps/transport/client/yarn.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,10 @@
481481
"@babel/helper-module-transforms" "^7.28.6"
482482
"@babel/helper-plugin-utils" "^7.28.6"
483483

484-
"@babel/plugin-transform-modules-systemjs@^7.29.0":
485-
version "7.29.0"
486-
resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz#e458a95a17807c415924106a3ff188a3b8dee964"
487-
integrity sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==
484+
"@babel/plugin-transform-modules-systemjs@^7.29.0", "@babel/plugin-transform-modules-systemjs@^7.29.4":
485+
version "7.29.4"
486+
resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz#f621105da99919c15cf4bde6fcc7346ef95e7b20"
487+
integrity sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==
488488
dependencies:
489489
"@babel/helper-module-transforms" "^7.28.6"
490490
"@babel/helper-plugin-utils" "^7.28.6"
@@ -2507,10 +2507,10 @@ fast-levenshtein@^2.0.6:
25072507
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
25082508
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
25092509

2510-
fast-uri@^3.0.1:
2511-
version "3.1.0"
2512-
resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa"
2513-
integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==
2510+
fast-uri@^3.0.1, fast-uri@^3.1.2:
2511+
version "3.1.2"
2512+
resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz#8af3d4fc9d3e71b11572cc2673b514a7d1a8c8ec"
2513+
integrity sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==
25142514

25152515
fastest-levenshtein@^1.0.12, fastest-levenshtein@^1.0.16:
25162516
version "1.0.16"

generate_deps_changelogs.exs

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# and automatically edit the PR description with this.
1111
#
1212

13-
Mix.install([:jason, :req])
13+
Mix.install([:jason])
1414

1515
defmodule Scanner do
1616
def scan(mix_lock_content) do
@@ -71,62 +71,93 @@ end)
7171
defmodule YarnScanner do
7272
@path "apps/transport/client"
7373

74-
def at(:local),
75-
do: parse(File.read!("#{@path}/yarn.lock"), File.read!("#{@path}/package.json"))
74+
# name => sorted unique list of resolved versions (a name may appear at
75+
# several versions, since we bundle multiple versions at times).
76+
def versions(:local), do: parse(File.read!("#{@path}/yarn.lock"))
7677

77-
def at(ref) do
78-
{pj, 0} = System.cmd("git", ["show", "#{ref}:#{@path}/package.json"])
78+
def versions(ref) do
7979
{yl, 0} = System.cmd("git", ["show", "#{ref}:#{@path}/yarn.lock"])
80-
parse(yl, pj)
80+
parse(yl)
8181
end
8282

83-
def diff_url(name, v1, v2) do
84-
with {:ok, %{status: 200, body: body}} <- Req.get("https://registry.npmjs.org/#{name}"),
85-
url <- get_in(body, ["repository", "url"]) || "",
86-
[_, owner, repo] <- Regex.run(~r{github\.com[/:]([^/]+)/([^/.]+)}, url) do
87-
"https://github.com/#{owner}/#{repo}/compare/v#{v1}...v#{v2}"
88-
else
89-
_ -> "https://www.npmjs.com/package/#{name}?activeTab=versions"
90-
end
83+
# Names declared top-level in a ref's package.json (deps / devDeps /
84+
# resolutions). Used only to classify a dep into the top-level vs the
85+
# transitive section — not to filter anything out.
86+
def direct(:local), do: parse_direct(File.read!("#{@path}/package.json"))
87+
88+
def direct(ref) do
89+
{pj, 0} = System.cmd("git", ["show", "#{ref}:#{@path}/package.json"])
90+
parse_direct(pj)
9191
end
9292

93-
defp parse(lock, json) do
94-
direct =
95-
json
96-
|> Jason.decode!()
97-
|> Map.take(~w(dependencies devDependencies resolutions))
98-
|> Map.values()
99-
|> Enum.flat_map(&Map.keys/1)
100-
|> MapSet.new()
93+
defp parse_direct(json) do
94+
json
95+
|> Jason.decode!()
96+
|> Map.take(~w(dependencies devDependencies resolutions))
97+
|> Map.values()
98+
|> Enum.flat_map(&Map.keys/1)
99+
|> MapSet.new()
100+
end
101101

102+
# npmdiff.dev diffs the published tarballs (the npm equivalent of
103+
# diff.hex.pm). Scoped names need the scope slash percent-encoded.
104+
def diff_url(name, v1, v2) do
105+
"https://npmdiff.dev/#{String.replace(name, "/", "%2F")}/#{v1}/#{v2}/"
106+
end
107+
108+
defp parse(lock) do
102109
lock
103110
|> String.split("\n\n")
104111
|> Enum.reduce(%{}, fn block, acc ->
105112
with [_, name] <- Regex.run(~r/^"?((?:@[^\/"]+\/)?[^@"\s]+)@/m, block),
106-
true <- MapSet.member?(direct, name),
107113
[_, ver] <- Regex.run(~r/version "([^"]+)"/, block) do
108-
Map.put(acc, name, ver)
114+
Map.update(acc, name, [ver], &Enum.uniq([ver | &1]))
109115
else
110116
_ -> acc
111117
end
112118
end)
119+
|> Map.new(fn {name, vers} -> {name, Enum.sort(vers)} end)
113120
end
114121
end
115122

116-
IO.puts "\n### JS dependencies (top-level only)"
117-
IO.puts "(may include duplicates, since we bundle multiple versions at times)\n"
118-
yarn_master = YarnScanner.at("master")
119-
yarn_current = YarnScanner.at(:local)
120-
121-
(Map.keys(yarn_master) ++ Map.keys(yarn_current))
122-
|> Enum.uniq()
123-
|> Enum.sort()
124-
|> Enum.each(fn name ->
125-
case {yarn_master[name], yarn_current[name]} do
126-
{v1, v2} when not is_nil(v1) and not is_nil(v2) and v1 != v2 ->
127-
IO.puts "* #{YarnScanner.diff_url(name, v1, v2)}"
128-
{nil, v2} when not is_nil(v2) -> IO.puts "* ADDED: #{name}@#{v2}"
129-
{v1, nil} when not is_nil(v1) -> IO.puts "* REMOVED: #{name}@#{v1}"
130-
_ -> :ok
123+
yarn_master = YarnScanner.versions("master")
124+
yarn_current = YarnScanner.versions(:local)
125+
# Union of both refs so a name dropped from resolutions on one side is still
126+
# classified the same way.
127+
direct = MapSet.union(YarnScanner.direct("master"), YarnScanner.direct(:local))
128+
129+
# Same treatment for everyone; only the section a line lands in differs.
130+
render = fn name ->
131+
case {Map.get(yarn_master, name), Map.get(yarn_current, name)} do
132+
{same, same} ->
133+
nil
134+
135+
{nil, news} ->
136+
"* ADDED: #{name}@#{Enum.join(news, ", ")}"
137+
138+
{olds, nil} ->
139+
"* REMOVED: #{name}@#{Enum.join(olds, ", ")}"
140+
141+
{[old], [new]} ->
142+
"* #{YarnScanner.diff_url(name, old, new)}"
143+
144+
{olds, news} ->
145+
# Multi-version (bundled duplicates): no single tarball diff applies.
146+
"* #{name}: #{Enum.join(olds, ", ")}#{Enum.join(news, ", ")}"
131147
end
132-
end)
148+
end
149+
150+
{top_level, lock_only} =
151+
(Map.keys(yarn_master) ++ Map.keys(yarn_current))
152+
|> Enum.uniq()
153+
|> Enum.sort()
154+
|> Enum.map(&{&1, render.(&1)})
155+
|> Enum.reject(fn {_name, line} -> is_nil(line) end)
156+
|> Enum.split_with(fn {name, _line} -> MapSet.member?(direct, name) end)
157+
158+
IO.puts "\n### JS dependencies — top-level (package.json: dependencies / devDependencies / resolutions)\n"
159+
Enum.each(top_level, fn {_name, line} -> IO.puts(line) end)
160+
161+
IO.puts "\n### JS dependencies — transitive (yarn.lock only)"
162+
IO.puts "(may include duplicates, since we bundle multiple versions at times)\n"
163+
Enum.each(lock_only, fn {_name, line} -> IO.puts(line) end)

0 commit comments

Comments
 (0)