Restructure solution layout by module
This commit is contained in:
@@ -0,0 +1,464 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Connector.Common;
|
||||
using StellaOps.Concelier.Connector.Common.Http;
|
||||
using StellaOps.Concelier.Connector.Common.Testing;
|
||||
using StellaOps.Concelier.Connector.Vndr.Adobe;
|
||||
using StellaOps.Concelier.Connector.Vndr.Adobe.Configuration;
|
||||
using StellaOps.Concelier.Storage.Mongo;
|
||||
using StellaOps.Concelier.Storage.Mongo.Advisories;
|
||||
using StellaOps.Concelier.Storage.Mongo.Documents;
|
||||
using StellaOps.Concelier.Storage.Mongo.Dtos;
|
||||
using StellaOps.Concelier.Storage.Mongo.PsirtFlags;
|
||||
using StellaOps.Concelier.Testing;
|
||||
|
||||
namespace StellaOps.Concelier.Connector.Vndr.Adobe.Tests;
|
||||
|
||||
[Collection("mongo-fixture")]
|
||||
public sealed class AdobeConnectorFetchTests : IAsyncLifetime
|
||||
{
|
||||
private readonly MongoIntegrationFixture _fixture;
|
||||
private readonly FakeTimeProvider _timeProvider;
|
||||
|
||||
public AdobeConnectorFetchTests(MongoIntegrationFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
_timeProvider = new FakeTimeProvider(new DateTimeOffset(2025, 9, 10, 0, 0, 0, TimeSpan.Zero));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Fetch_WindowsIndexAndPersistsCursor()
|
||||
{
|
||||
var handler = new CannedHttpMessageHandler();
|
||||
await using var provider = await BuildServiceProviderAsync(handler);
|
||||
SeedIndex(handler);
|
||||
SeedDetail(handler);
|
||||
|
||||
var connector = provider.GetRequiredService<AdobeConnector>();
|
||||
await connector.FetchAsync(provider, CancellationToken.None);
|
||||
|
||||
var stateRepository = provider.GetRequiredService<ISourceStateRepository>();
|
||||
var state = await stateRepository.TryGetAsync(VndrAdobeConnectorPlugin.SourceName, CancellationToken.None);
|
||||
Assert.NotNull(state);
|
||||
var cursor = state!.Cursor;
|
||||
var pendingDocuments = ExtractGuidList(cursor, "pendingDocuments");
|
||||
Assert.Equal(2, pendingDocuments.Count);
|
||||
|
||||
// Re-seed responses to simulate unchanged fetch
|
||||
SeedIndex(handler);
|
||||
SeedDetail(handler);
|
||||
await connector.FetchAsync(provider, CancellationToken.None);
|
||||
|
||||
state = await stateRepository.TryGetAsync(VndrAdobeConnectorPlugin.SourceName, CancellationToken.None);
|
||||
Assert.NotNull(state);
|
||||
cursor = state!.Cursor;
|
||||
var afterPending = ExtractGuidList(cursor, "pendingDocuments");
|
||||
Assert.Equal(pendingDocuments.OrderBy(static id => id), afterPending.OrderBy(static id => id));
|
||||
|
||||
var fetchCache = cursor.TryGetValue("fetchCache", out var fetchCacheValue) && fetchCacheValue is BsonDocument cacheDoc
|
||||
? cacheDoc.Elements.Select(static e => e.Name).ToArray()
|
||||
: Array.Empty<string>();
|
||||
Assert.Contains("https://helpx.adobe.com/security/products/acrobat/apsb25-85.html", fetchCache);
|
||||
Assert.Contains("https://helpx.adobe.com/security/products/premiere_pro/apsb25-87.html", fetchCache);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Parse_ProducesDtoAndClearsPendingDocuments()
|
||||
{
|
||||
var handler = new CannedHttpMessageHandler();
|
||||
await using var provider = await BuildServiceProviderAsync(handler);
|
||||
SeedIndex(handler);
|
||||
SeedDetail(handler);
|
||||
|
||||
var connector = provider.GetRequiredService<AdobeConnector>();
|
||||
await connector.FetchAsync(provider, CancellationToken.None);
|
||||
await connector.ParseAsync(provider, CancellationToken.None);
|
||||
await connector.MapAsync(provider, CancellationToken.None);
|
||||
|
||||
var documentStore = provider.GetRequiredService<IDocumentStore>();
|
||||
var dtoStore = provider.GetRequiredService<IDtoStore>();
|
||||
var advisoryStore = provider.GetRequiredService<IAdvisoryStore>();
|
||||
var psirtStore = provider.GetRequiredService<IPsirtFlagStore>();
|
||||
var stateRepository = provider.GetRequiredService<ISourceStateRepository>();
|
||||
|
||||
var document = await documentStore.FindBySourceAndUriAsync(
|
||||
VndrAdobeConnectorPlugin.SourceName,
|
||||
"https://helpx.adobe.com/security/products/acrobat/apsb25-85.html",
|
||||
CancellationToken.None);
|
||||
|
||||
Assert.NotNull(document);
|
||||
|
||||
var dtoRecord = await dtoStore.FindByDocumentIdAsync(document!.Id, CancellationToken.None);
|
||||
Assert.NotNull(dtoRecord);
|
||||
Assert.Equal("adobe.bulletin.v1", dtoRecord!.SchemaVersion);
|
||||
var payload = dtoRecord.Payload;
|
||||
Assert.Equal("APSB25-85", payload.GetValue("advisoryId").AsString);
|
||||
Assert.Equal("https://helpx.adobe.com/security/products/acrobat/apsb25-85.html", payload.GetValue("detailUrl").AsString);
|
||||
|
||||
var products = payload.GetValue("products").AsBsonArray
|
||||
.Select(static value => value.AsBsonDocument)
|
||||
.ToArray();
|
||||
Assert.NotEmpty(products);
|
||||
var acrobatWindowsProduct = Assert.Single(
|
||||
products,
|
||||
static doc => string.Equals(doc.GetValue("product").AsString, "Acrobat DC", StringComparison.Ordinal)
|
||||
&& string.Equals(doc.GetValue("platform").AsString, "Windows", StringComparison.Ordinal));
|
||||
Assert.Equal("25.001.20672 and earlier", acrobatWindowsProduct.GetValue("affectedVersion").AsString);
|
||||
Assert.Equal("25.001.20680", acrobatWindowsProduct.GetValue("updatedVersion").AsString);
|
||||
|
||||
var acrobatMacProduct = Assert.Single(
|
||||
products,
|
||||
static doc => string.Equals(doc.GetValue("product").AsString, "Acrobat DC", StringComparison.Ordinal)
|
||||
&& string.Equals(doc.GetValue("platform").AsString, "macOS", StringComparison.Ordinal));
|
||||
Assert.Equal("25.001.20668 and earlier", acrobatMacProduct.GetValue("affectedVersion").AsString);
|
||||
Assert.Equal("25.001.20678", acrobatMacProduct.GetValue("updatedVersion").AsString);
|
||||
|
||||
var state = await stateRepository.TryGetAsync(VndrAdobeConnectorPlugin.SourceName, CancellationToken.None);
|
||||
Assert.NotNull(state);
|
||||
var cursor = state!.Cursor;
|
||||
Assert.True(!cursor.TryGetValue("pendingDocuments", out _)
|
||||
|| cursor.GetValue("pendingDocuments").AsBsonArray.Count == 0);
|
||||
Assert.True(!cursor.TryGetValue("pendingMappings", out _)
|
||||
|| cursor.GetValue("pendingMappings").AsBsonArray.Count == 0);
|
||||
|
||||
var advisories = await advisoryStore.GetRecentAsync(5, CancellationToken.None);
|
||||
Assert.Equal(2, advisories.Count);
|
||||
|
||||
var acrobatAdvisory = advisories.Single(a => a.AdvisoryKey == "APSB25-85");
|
||||
Assert.Contains("APSB25-85", acrobatAdvisory.Aliases);
|
||||
Assert.Equal(
|
||||
acrobatAdvisory.References.Select(static r => r.Url).Distinct(StringComparer.OrdinalIgnoreCase).Count(),
|
||||
acrobatAdvisory.References.Length);
|
||||
var acrobatWindowsPackage = Assert.Single(
|
||||
acrobatAdvisory.AffectedPackages,
|
||||
pkg => string.Equals(pkg.Identifier, "Acrobat DC", StringComparison.Ordinal)
|
||||
&& string.Equals(pkg.Platform, "Windows", StringComparison.Ordinal));
|
||||
var acrobatWindowsRange = Assert.Single(acrobatWindowsPackage.VersionRanges);
|
||||
Assert.Equal("vendor", acrobatWindowsRange.RangeKind);
|
||||
Assert.Equal("25.001.20680", acrobatWindowsRange.FixedVersion);
|
||||
Assert.Equal("25.001.20672", acrobatWindowsRange.LastAffectedVersion);
|
||||
Assert.NotNull(acrobatWindowsRange.Primitives);
|
||||
var windowsExtensions = acrobatWindowsRange.Primitives!.VendorExtensions;
|
||||
Assert.NotNull(windowsExtensions);
|
||||
Assert.True(windowsExtensions!.TryGetValue("adobe.affected.raw", out var rawAffectedWin));
|
||||
Assert.Equal("25.001.20672 and earlier", rawAffectedWin);
|
||||
Assert.True(windowsExtensions.TryGetValue("adobe.updated.raw", out var rawUpdatedWin));
|
||||
Assert.Equal("25.001.20680", rawUpdatedWin);
|
||||
Assert.Contains(
|
||||
AffectedPackageStatusCatalog.Fixed,
|
||||
acrobatWindowsPackage.Statuses.Select(static status => status.Status));
|
||||
var windowsNormalized = Assert.Single(acrobatWindowsPackage.NormalizedVersions.ToArray());
|
||||
Assert.Equal(NormalizedVersionSchemes.SemVer, windowsNormalized.Scheme);
|
||||
Assert.Equal(NormalizedVersionRuleTypes.LessThan, windowsNormalized.Type);
|
||||
Assert.Equal("25.1.20680", windowsNormalized.Max);
|
||||
Assert.False(windowsNormalized.MaxInclusive);
|
||||
Assert.Equal("adobe:Acrobat DC:Windows", windowsNormalized.Notes);
|
||||
|
||||
var acrobatMacPackage = Assert.Single(
|
||||
acrobatAdvisory.AffectedPackages,
|
||||
pkg => string.Equals(pkg.Identifier, "Acrobat DC", StringComparison.Ordinal)
|
||||
&& string.Equals(pkg.Platform, "macOS", StringComparison.Ordinal));
|
||||
var acrobatMacRange = Assert.Single(acrobatMacPackage.VersionRanges);
|
||||
Assert.Equal("vendor", acrobatMacRange.RangeKind);
|
||||
Assert.Equal("25.001.20678", acrobatMacRange.FixedVersion);
|
||||
Assert.Equal("25.001.20668", acrobatMacRange.LastAffectedVersion);
|
||||
Assert.NotNull(acrobatMacRange.Primitives);
|
||||
var macExtensions = acrobatMacRange.Primitives!.VendorExtensions;
|
||||
Assert.NotNull(macExtensions);
|
||||
Assert.True(macExtensions!.TryGetValue("adobe.affected.raw", out var rawAffectedMac));
|
||||
Assert.Equal("25.001.20668 and earlier", rawAffectedMac);
|
||||
Assert.True(macExtensions.TryGetValue("adobe.updated.raw", out var rawUpdatedMac));
|
||||
Assert.Equal("25.001.20678", rawUpdatedMac);
|
||||
Assert.Contains(
|
||||
AffectedPackageStatusCatalog.Fixed,
|
||||
acrobatMacPackage.Statuses.Select(static status => status.Status));
|
||||
var macNormalized = Assert.Single(acrobatMacPackage.NormalizedVersions.ToArray());
|
||||
Assert.Equal(NormalizedVersionSchemes.SemVer, macNormalized.Scheme);
|
||||
Assert.Equal(NormalizedVersionRuleTypes.LessThan, macNormalized.Type);
|
||||
Assert.Equal("25.1.20678", macNormalized.Max);
|
||||
Assert.False(macNormalized.MaxInclusive);
|
||||
Assert.Equal("adobe:Acrobat DC:macOS", macNormalized.Notes);
|
||||
|
||||
var premiereAdvisory = advisories.Single(a => a.AdvisoryKey == "APSB25-87");
|
||||
Assert.Contains("APSB25-87", premiereAdvisory.Aliases);
|
||||
Assert.Equal(
|
||||
premiereAdvisory.References.Select(static r => r.Url).Distinct(StringComparer.OrdinalIgnoreCase).Count(),
|
||||
premiereAdvisory.References.Length);
|
||||
var premiereWindowsPackage = Assert.Single(
|
||||
premiereAdvisory.AffectedPackages,
|
||||
pkg => string.Equals(pkg.Identifier, "Premiere Pro", StringComparison.Ordinal)
|
||||
&& string.Equals(pkg.Platform, "Windows", StringComparison.Ordinal));
|
||||
var premiereWindowsRange = Assert.Single(premiereWindowsPackage.VersionRanges);
|
||||
Assert.Equal("24.6", premiereWindowsRange.FixedVersion);
|
||||
Assert.Equal("24.5", premiereWindowsRange.LastAffectedVersion);
|
||||
Assert.NotNull(premiereWindowsRange.Primitives);
|
||||
var premiereWindowsExtensions = premiereWindowsRange.Primitives!.VendorExtensions;
|
||||
Assert.NotNull(premiereWindowsExtensions);
|
||||
Assert.True(premiereWindowsExtensions!.TryGetValue("adobe.priority", out var premierePriorityWin));
|
||||
Assert.Equal("Priority 3", premierePriorityWin);
|
||||
Assert.Contains(
|
||||
AffectedPackageStatusCatalog.Fixed,
|
||||
premiereWindowsPackage.Statuses.Select(static status => status.Status));
|
||||
var premiereWinNormalized = Assert.Single(premiereWindowsPackage.NormalizedVersions.ToArray());
|
||||
Assert.Equal(NormalizedVersionSchemes.SemVer, premiereWinNormalized.Scheme);
|
||||
Assert.Equal(NormalizedVersionRuleTypes.LessThan, premiereWinNormalized.Type);
|
||||
Assert.Equal("24.6", premiereWinNormalized.Max);
|
||||
Assert.False(premiereWinNormalized.MaxInclusive);
|
||||
Assert.Equal("adobe:Premiere Pro:Windows", premiereWinNormalized.Notes);
|
||||
|
||||
var premiereMacPackage = Assert.Single(
|
||||
premiereAdvisory.AffectedPackages,
|
||||
pkg => string.Equals(pkg.Identifier, "Premiere Pro", StringComparison.Ordinal)
|
||||
&& string.Equals(pkg.Platform, "macOS", StringComparison.Ordinal));
|
||||
var premiereMacRange = Assert.Single(premiereMacPackage.VersionRanges);
|
||||
Assert.Equal("24.6", premiereMacRange.FixedVersion);
|
||||
Assert.Equal("24.5", premiereMacRange.LastAffectedVersion);
|
||||
Assert.NotNull(premiereMacRange.Primitives);
|
||||
var premiereMacExtensions = premiereMacRange.Primitives!.VendorExtensions;
|
||||
Assert.NotNull(premiereMacExtensions);
|
||||
Assert.True(premiereMacExtensions!.TryGetValue("adobe.priority", out var premierePriorityMac));
|
||||
Assert.Equal("Priority 3", premierePriorityMac);
|
||||
Assert.Contains(
|
||||
AffectedPackageStatusCatalog.Fixed,
|
||||
premiereMacPackage.Statuses.Select(static status => status.Status));
|
||||
var premiereMacNormalized = Assert.Single(premiereMacPackage.NormalizedVersions.ToArray());
|
||||
Assert.Equal(NormalizedVersionSchemes.SemVer, premiereMacNormalized.Scheme);
|
||||
Assert.Equal(NormalizedVersionRuleTypes.LessThan, premiereMacNormalized.Type);
|
||||
Assert.Equal("24.6", premiereMacNormalized.Max);
|
||||
Assert.False(premiereMacNormalized.MaxInclusive);
|
||||
Assert.Equal("adobe:Premiere Pro:macOS", premiereMacNormalized.Notes);
|
||||
|
||||
var ordered = advisories.OrderBy(static a => a.AdvisoryKey, StringComparer.Ordinal).ToArray();
|
||||
var snapshot = SnapshotSerializer.ToSnapshot(ordered);
|
||||
var expected = ReadFixture("adobe-advisories.snapshot.json");
|
||||
var normalizedSnapshot = NormalizeLineEndings(snapshot);
|
||||
var normalizedExpected = NormalizeLineEndings(expected);
|
||||
if (!string.Equals(normalizedExpected, normalizedSnapshot, StringComparison.Ordinal))
|
||||
{
|
||||
var actualPath = Path.Combine(AppContext.BaseDirectory, "Source", "Vndr", "Adobe", "Fixtures", "adobe-advisories.actual.json");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(actualPath)!);
|
||||
File.WriteAllText(actualPath, snapshot);
|
||||
}
|
||||
|
||||
Assert.Equal(normalizedExpected, normalizedSnapshot);
|
||||
|
||||
var flagsCollection = _fixture.Database.GetCollection<BsonDocument>("psirt_flags");
|
||||
var rawFlags = await flagsCollection.Find(Builders<BsonDocument>.Filter.Empty).ToListAsync();
|
||||
Assert.NotEmpty(rawFlags);
|
||||
|
||||
var flagRecord = rawFlags.Single(doc => doc["_id"].AsString == "APSB25-87");
|
||||
Assert.Equal("Adobe", flagRecord["vendor"].AsString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Fetch_WithNotModifiedResponses_KeepsDocumentsMapped()
|
||||
{
|
||||
var handler = new CannedHttpMessageHandler();
|
||||
await using var provider = await BuildServiceProviderAsync(handler);
|
||||
SeedIndex(handler);
|
||||
SeedDetail(handler);
|
||||
|
||||
var connector = provider.GetRequiredService<AdobeConnector>();
|
||||
await connector.FetchAsync(provider, CancellationToken.None);
|
||||
await connector.ParseAsync(provider, CancellationToken.None);
|
||||
await connector.MapAsync(provider, CancellationToken.None);
|
||||
|
||||
var documentStore = provider.GetRequiredService<IDocumentStore>();
|
||||
var acrobatDoc = await documentStore.FindBySourceAndUriAsync(
|
||||
VndrAdobeConnectorPlugin.SourceName,
|
||||
"https://helpx.adobe.com/security/products/acrobat/apsb25-85.html",
|
||||
CancellationToken.None);
|
||||
Assert.NotNull(acrobatDoc);
|
||||
Assert.Equal(DocumentStatuses.Mapped, acrobatDoc!.Status);
|
||||
|
||||
var premiereDoc = await documentStore.FindBySourceAndUriAsync(
|
||||
VndrAdobeConnectorPlugin.SourceName,
|
||||
"https://helpx.adobe.com/security/products/premiere_pro/apsb25-87.html",
|
||||
CancellationToken.None);
|
||||
Assert.NotNull(premiereDoc);
|
||||
Assert.Equal(DocumentStatuses.Mapped, premiereDoc!.Status);
|
||||
|
||||
SeedIndex(handler);
|
||||
SeedDetailNotModified(handler);
|
||||
|
||||
await connector.FetchAsync(provider, CancellationToken.None);
|
||||
|
||||
acrobatDoc = await documentStore.FindBySourceAndUriAsync(
|
||||
VndrAdobeConnectorPlugin.SourceName,
|
||||
"https://helpx.adobe.com/security/products/acrobat/apsb25-85.html",
|
||||
CancellationToken.None);
|
||||
Assert.NotNull(acrobatDoc);
|
||||
Assert.Equal(DocumentStatuses.Mapped, acrobatDoc!.Status);
|
||||
|
||||
premiereDoc = await documentStore.FindBySourceAndUriAsync(
|
||||
VndrAdobeConnectorPlugin.SourceName,
|
||||
"https://helpx.adobe.com/security/products/premiere_pro/apsb25-87.html",
|
||||
CancellationToken.None);
|
||||
Assert.NotNull(premiereDoc);
|
||||
Assert.Equal(DocumentStatuses.Mapped, premiereDoc!.Status);
|
||||
|
||||
var stateRepository = provider.GetRequiredService<ISourceStateRepository>();
|
||||
var state = await stateRepository.TryGetAsync(VndrAdobeConnectorPlugin.SourceName, CancellationToken.None);
|
||||
Assert.NotNull(state);
|
||||
Assert.True(state!.Cursor.TryGetValue("pendingDocuments", out var pendingDocs) && pendingDocs.AsBsonArray.Count == 0);
|
||||
Assert.True(state.Cursor.TryGetValue("pendingMappings", out var pendingMap) && pendingMap.AsBsonArray.Count == 0);
|
||||
}
|
||||
|
||||
private async Task<ServiceProvider> BuildServiceProviderAsync(CannedHttpMessageHandler handler)
|
||||
{
|
||||
await _fixture.Client.DropDatabaseAsync(_fixture.Database.DatabaseNamespace.DatabaseName);
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddLogging(builder => builder.AddProvider(NullLoggerProvider.Instance));
|
||||
services.AddSingleton<TimeProvider>(_timeProvider);
|
||||
services.AddSingleton(handler);
|
||||
|
||||
services.AddMongoStorage(options =>
|
||||
{
|
||||
options.ConnectionString = _fixture.Runner.ConnectionString;
|
||||
options.DatabaseName = _fixture.Database.DatabaseNamespace.DatabaseName;
|
||||
options.CommandTimeout = TimeSpan.FromSeconds(5);
|
||||
});
|
||||
|
||||
services.AddSourceCommon();
|
||||
services.AddAdobeConnector(opts =>
|
||||
{
|
||||
opts.IndexUri = new Uri("https://helpx.adobe.com/security/security-bulletin.html");
|
||||
opts.InitialBackfill = TimeSpan.FromDays(30);
|
||||
opts.WindowOverlap = TimeSpan.FromDays(2);
|
||||
});
|
||||
|
||||
services.Configure<HttpClientFactoryOptions>(AdobeOptions.HttpClientName, builderOptions =>
|
||||
{
|
||||
builderOptions.HttpMessageHandlerBuilderActions.Add(builder =>
|
||||
{
|
||||
builder.PrimaryHandler = handler;
|
||||
});
|
||||
});
|
||||
|
||||
var provider = services.BuildServiceProvider();
|
||||
var bootstrapper = provider.GetRequiredService<MongoBootstrapper>();
|
||||
await bootstrapper.InitializeAsync(CancellationToken.None);
|
||||
return provider;
|
||||
}
|
||||
|
||||
private static void SeedIndex(CannedHttpMessageHandler handler)
|
||||
{
|
||||
var indexUri = new Uri("https://helpx.adobe.com/security/security-bulletin.html");
|
||||
var indexHtml = ReadFixture("adobe-index.html");
|
||||
handler.AddTextResponse(indexUri, indexHtml, "text/html");
|
||||
}
|
||||
|
||||
private static void SeedDetail(CannedHttpMessageHandler handler)
|
||||
{
|
||||
AddDetailResponse(
|
||||
handler,
|
||||
new Uri("https://helpx.adobe.com/security/products/acrobat/apsb25-85.html"),
|
||||
"adobe-detail-apsb25-85.html",
|
||||
"\"apsb25-85\"");
|
||||
|
||||
AddDetailResponse(
|
||||
handler,
|
||||
new Uri("https://helpx.adobe.com/security/products/premiere_pro/apsb25-87.html"),
|
||||
"adobe-detail-apsb25-87.html",
|
||||
"\"apsb25-87\"");
|
||||
}
|
||||
|
||||
private static void SeedDetailNotModified(CannedHttpMessageHandler handler)
|
||||
{
|
||||
AddNotModifiedResponse(
|
||||
handler,
|
||||
new Uri("https://helpx.adobe.com/security/products/acrobat/apsb25-85.html"),
|
||||
"\"apsb25-85\"");
|
||||
|
||||
AddNotModifiedResponse(
|
||||
handler,
|
||||
new Uri("https://helpx.adobe.com/security/products/premiere_pro/apsb25-87.html"),
|
||||
"\"apsb25-87\"");
|
||||
}
|
||||
|
||||
private static void AddDetailResponse(CannedHttpMessageHandler handler, Uri uri, string fixture, string? etag)
|
||||
{
|
||||
handler.AddResponse(uri, () =>
|
||||
{
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(ReadFixture(fixture), Encoding.UTF8, "text/html"),
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(etag))
|
||||
{
|
||||
response.Headers.ETag = new EntityTagHeaderValue(etag);
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
private static void AddNotModifiedResponse(CannedHttpMessageHandler handler, Uri uri, string? etag)
|
||||
{
|
||||
handler.AddResponse(uri, () =>
|
||||
{
|
||||
var response = new HttpResponseMessage(HttpStatusCode.NotModified);
|
||||
if (!string.IsNullOrEmpty(etag))
|
||||
{
|
||||
response.Headers.ETag = new EntityTagHeaderValue(etag);
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
private static List<Guid> ExtractGuidList(BsonDocument cursor, string field)
|
||||
{
|
||||
if (!cursor.TryGetValue(field, out var value) || value is not BsonArray array)
|
||||
{
|
||||
return new List<Guid>();
|
||||
}
|
||||
|
||||
var list = new List<Guid>(array.Count);
|
||||
foreach (var element in array)
|
||||
{
|
||||
if (Guid.TryParse(element.AsString, out var guid))
|
||||
{
|
||||
list.Add(guid);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static string ReadFixture(string name)
|
||||
{
|
||||
var candidate = Path.Combine(AppContext.BaseDirectory, "Adobe", "Fixtures", name);
|
||||
if (!File.Exists(candidate))
|
||||
{
|
||||
candidate = Path.Combine(AppContext.BaseDirectory, "Source", "Vndr", "Adobe", "Fixtures", name);
|
||||
}
|
||||
|
||||
return File.ReadAllText(candidate);
|
||||
}
|
||||
|
||||
private static string NormalizeLineEndings(string value)
|
||||
=> value.Replace("\r\n", "\n", StringComparison.Ordinal);
|
||||
|
||||
public Task InitializeAsync() => Task.CompletedTask;
|
||||
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
[
|
||||
{
|
||||
"advisoryKey": "APSB25-85",
|
||||
"affectedPackages": [
|
||||
{
|
||||
"type": "vendor",
|
||||
"identifier": "Acrobat DC",
|
||||
"platform": "Windows",
|
||||
"versionRanges": [
|
||||
{
|
||||
"fixedVersion": "25.001.20680",
|
||||
"introducedVersion": null,
|
||||
"lastAffectedVersion": "25.001.20672",
|
||||
"primitives": {
|
||||
"evr": null,
|
||||
"hasVendorExtensions": true,
|
||||
"nevra": null,
|
||||
"semVer": {
|
||||
"constraintExpression": null,
|
||||
"exactValue": null,
|
||||
"fixed": "25.1.20680",
|
||||
"fixedInclusive": false,
|
||||
"introduced": null,
|
||||
"introducedInclusive": true,
|
||||
"lastAffected": "25.1.20672",
|
||||
"lastAffectedInclusive": true,
|
||||
"style": "lessThan"
|
||||
},
|
||||
"vendorExtensions": {
|
||||
"adobe.track": "Continuous",
|
||||
"adobe.platform": "Windows",
|
||||
"adobe.affected.raw": "25.001.20672 and earlier",
|
||||
"adobe.updated.raw": "25.001.20680",
|
||||
"adobe.priority": "Priority 2",
|
||||
"adobe.availability": "Available"
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "range",
|
||||
"value": "Acrobat DC:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"rangeExpression": "25.001.20672 and earlier",
|
||||
"rangeKind": "vendor"
|
||||
}
|
||||
],
|
||||
"normalizedVersions": [
|
||||
{
|
||||
"scheme": "semver",
|
||||
"type": "lt",
|
||||
"min": null,
|
||||
"minInclusive": null,
|
||||
"max": "25.1.20680",
|
||||
"maxInclusive": false,
|
||||
"value": null,
|
||||
"notes": "adobe:Acrobat DC:Windows"
|
||||
}
|
||||
],
|
||||
"statuses": [
|
||||
{
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat DC:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"status": "fixed"
|
||||
}
|
||||
],
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat DC:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "vendor",
|
||||
"identifier": "Acrobat DC",
|
||||
"platform": "macOS",
|
||||
"versionRanges": [
|
||||
{
|
||||
"fixedVersion": "25.001.20678",
|
||||
"introducedVersion": null,
|
||||
"lastAffectedVersion": "25.001.20668",
|
||||
"primitives": {
|
||||
"evr": null,
|
||||
"hasVendorExtensions": true,
|
||||
"nevra": null,
|
||||
"semVer": {
|
||||
"constraintExpression": null,
|
||||
"exactValue": null,
|
||||
"fixed": "25.1.20678",
|
||||
"fixedInclusive": false,
|
||||
"introduced": null,
|
||||
"introducedInclusive": true,
|
||||
"lastAffected": "25.1.20668",
|
||||
"lastAffectedInclusive": true,
|
||||
"style": "lessThan"
|
||||
},
|
||||
"vendorExtensions": {
|
||||
"adobe.track": "Continuous",
|
||||
"adobe.platform": "macOS",
|
||||
"adobe.affected.raw": "25.001.20668 and earlier",
|
||||
"adobe.updated.raw": "25.001.20678",
|
||||
"adobe.priority": "Priority 2",
|
||||
"adobe.availability": "Available"
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "range",
|
||||
"value": "Acrobat DC:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"rangeExpression": "25.001.20668 and earlier",
|
||||
"rangeKind": "vendor"
|
||||
}
|
||||
],
|
||||
"normalizedVersions": [
|
||||
{
|
||||
"scheme": "semver",
|
||||
"type": "lt",
|
||||
"min": null,
|
||||
"minInclusive": null,
|
||||
"max": "25.1.20678",
|
||||
"maxInclusive": false,
|
||||
"value": null,
|
||||
"notes": "adobe:Acrobat DC:macOS"
|
||||
}
|
||||
],
|
||||
"statuses": [
|
||||
{
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat DC:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"status": "fixed"
|
||||
}
|
||||
],
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat DC:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "vendor",
|
||||
"identifier": "Acrobat Reader DC",
|
||||
"platform": "Windows",
|
||||
"versionRanges": [
|
||||
{
|
||||
"fixedVersion": "25.001.20680",
|
||||
"introducedVersion": null,
|
||||
"lastAffectedVersion": "25.001.20672",
|
||||
"primitives": {
|
||||
"evr": null,
|
||||
"hasVendorExtensions": true,
|
||||
"nevra": null,
|
||||
"semVer": {
|
||||
"constraintExpression": null,
|
||||
"exactValue": null,
|
||||
"fixed": "25.1.20680",
|
||||
"fixedInclusive": false,
|
||||
"introduced": null,
|
||||
"introducedInclusive": true,
|
||||
"lastAffected": "25.1.20672",
|
||||
"lastAffectedInclusive": true,
|
||||
"style": "lessThan"
|
||||
},
|
||||
"vendorExtensions": {
|
||||
"adobe.track": "Continuous",
|
||||
"adobe.platform": "Windows",
|
||||
"adobe.affected.raw": "25.001.20672 and earlier",
|
||||
"adobe.updated.raw": "25.001.20680",
|
||||
"adobe.priority": "Priority 2",
|
||||
"adobe.availability": "Available"
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "range",
|
||||
"value": "Acrobat Reader DC:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"rangeExpression": "25.001.20672 and earlier",
|
||||
"rangeKind": "vendor"
|
||||
}
|
||||
],
|
||||
"normalizedVersions": [
|
||||
{
|
||||
"scheme": "semver",
|
||||
"type": "lt",
|
||||
"min": null,
|
||||
"minInclusive": null,
|
||||
"max": "25.1.20680",
|
||||
"maxInclusive": false,
|
||||
"value": null,
|
||||
"notes": "adobe:Acrobat Reader DC:Windows"
|
||||
}
|
||||
],
|
||||
"statuses": [
|
||||
{
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat Reader DC:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"status": "fixed"
|
||||
}
|
||||
],
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat Reader DC:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "vendor",
|
||||
"identifier": "Acrobat Reader DC",
|
||||
"platform": "macOS",
|
||||
"versionRanges": [
|
||||
{
|
||||
"fixedVersion": "25.001.20678",
|
||||
"introducedVersion": null,
|
||||
"lastAffectedVersion": "25.001.20668",
|
||||
"primitives": {
|
||||
"evr": null,
|
||||
"hasVendorExtensions": true,
|
||||
"nevra": null,
|
||||
"semVer": {
|
||||
"constraintExpression": null,
|
||||
"exactValue": null,
|
||||
"fixed": "25.1.20678",
|
||||
"fixedInclusive": false,
|
||||
"introduced": null,
|
||||
"introducedInclusive": true,
|
||||
"lastAffected": "25.1.20668",
|
||||
"lastAffectedInclusive": true,
|
||||
"style": "lessThan"
|
||||
},
|
||||
"vendorExtensions": {
|
||||
"adobe.track": "Continuous",
|
||||
"adobe.platform": "macOS",
|
||||
"adobe.affected.raw": "25.001.20668 and earlier",
|
||||
"adobe.updated.raw": "25.001.20678",
|
||||
"adobe.priority": "Priority 2",
|
||||
"adobe.availability": "Available"
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "range",
|
||||
"value": "Acrobat Reader DC:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"rangeExpression": "25.001.20668 and earlier",
|
||||
"rangeKind": "vendor"
|
||||
}
|
||||
],
|
||||
"normalizedVersions": [
|
||||
{
|
||||
"scheme": "semver",
|
||||
"type": "lt",
|
||||
"min": null,
|
||||
"minInclusive": null,
|
||||
"max": "25.1.20678",
|
||||
"maxInclusive": false,
|
||||
"value": null,
|
||||
"notes": "adobe:Acrobat Reader DC:macOS"
|
||||
}
|
||||
],
|
||||
"statuses": [
|
||||
{
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat Reader DC:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"status": "fixed"
|
||||
}
|
||||
],
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Acrobat Reader DC:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"APSB25-85"
|
||||
],
|
||||
"credits": [],
|
||||
"cvssMetrics": [],
|
||||
"exploitKnown": false,
|
||||
"language": "en",
|
||||
"modified": null,
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "parser",
|
||||
"value": "APSB25-85",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
],
|
||||
"published": "2025-09-09T00:00:00+00:00",
|
||||
"references": [
|
||||
{
|
||||
"kind": "advisory",
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "parser",
|
||||
"value": "APSB25-85",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"sourceTag": "adobe-psirt",
|
||||
"summary": "Date published: September 9, 2025",
|
||||
"url": "https://helpx.adobe.com/security/products/acrobat/apsb25-85.html"
|
||||
}
|
||||
],
|
||||
"severity": null,
|
||||
"summary": "Date published: September 9, 2025",
|
||||
"title": "APSB25-85: Security update available for Adobe Acrobat Reader"
|
||||
},
|
||||
{
|
||||
"advisoryKey": "APSB25-87",
|
||||
"affectedPackages": [
|
||||
{
|
||||
"type": "vendor",
|
||||
"identifier": "Premiere Pro",
|
||||
"platform": "Windows",
|
||||
"versionRanges": [
|
||||
{
|
||||
"fixedVersion": "24.6",
|
||||
"introducedVersion": null,
|
||||
"lastAffectedVersion": "24.5",
|
||||
"primitives": {
|
||||
"evr": null,
|
||||
"hasVendorExtensions": true,
|
||||
"nevra": null,
|
||||
"semVer": {
|
||||
"constraintExpression": null,
|
||||
"exactValue": null,
|
||||
"fixed": "24.6",
|
||||
"fixedInclusive": false,
|
||||
"introduced": null,
|
||||
"introducedInclusive": true,
|
||||
"lastAffected": "24.5",
|
||||
"lastAffectedInclusive": true,
|
||||
"style": "lessThan"
|
||||
},
|
||||
"vendorExtensions": {
|
||||
"adobe.track": "Quarterly",
|
||||
"adobe.platform": "Windows",
|
||||
"adobe.affected.raw": "24.5 and earlier",
|
||||
"adobe.updated.raw": "24.6",
|
||||
"adobe.priority": "Priority 3",
|
||||
"adobe.availability": "Available"
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "range",
|
||||
"value": "Premiere Pro:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"rangeExpression": "24.5 and earlier",
|
||||
"rangeKind": "vendor"
|
||||
}
|
||||
],
|
||||
"normalizedVersions": [
|
||||
{
|
||||
"scheme": "semver",
|
||||
"type": "lt",
|
||||
"min": null,
|
||||
"minInclusive": null,
|
||||
"max": "24.6",
|
||||
"maxInclusive": false,
|
||||
"value": null,
|
||||
"notes": "adobe:Premiere Pro:Windows"
|
||||
}
|
||||
],
|
||||
"statuses": [
|
||||
{
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Premiere Pro:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"status": "fixed"
|
||||
}
|
||||
],
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Premiere Pro:Windows",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "vendor",
|
||||
"identifier": "Premiere Pro",
|
||||
"platform": "macOS",
|
||||
"versionRanges": [
|
||||
{
|
||||
"fixedVersion": "24.6",
|
||||
"introducedVersion": null,
|
||||
"lastAffectedVersion": "24.5",
|
||||
"primitives": {
|
||||
"evr": null,
|
||||
"hasVendorExtensions": true,
|
||||
"nevra": null,
|
||||
"semVer": {
|
||||
"constraintExpression": null,
|
||||
"exactValue": null,
|
||||
"fixed": "24.6",
|
||||
"fixedInclusive": false,
|
||||
"introduced": null,
|
||||
"introducedInclusive": true,
|
||||
"lastAffected": "24.5",
|
||||
"lastAffectedInclusive": true,
|
||||
"style": "lessThan"
|
||||
},
|
||||
"vendorExtensions": {
|
||||
"adobe.track": "Quarterly",
|
||||
"adobe.platform": "macOS",
|
||||
"adobe.affected.raw": "24.5 and earlier",
|
||||
"adobe.updated.raw": "24.6",
|
||||
"adobe.priority": "Priority 3",
|
||||
"adobe.availability": "Available"
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "range",
|
||||
"value": "Premiere Pro:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"rangeExpression": "24.5 and earlier",
|
||||
"rangeKind": "vendor"
|
||||
}
|
||||
],
|
||||
"normalizedVersions": [
|
||||
{
|
||||
"scheme": "semver",
|
||||
"type": "lt",
|
||||
"min": null,
|
||||
"minInclusive": null,
|
||||
"max": "24.6",
|
||||
"maxInclusive": false,
|
||||
"value": null,
|
||||
"notes": "adobe:Premiere Pro:macOS"
|
||||
}
|
||||
],
|
||||
"statuses": [
|
||||
{
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Premiere Pro:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"status": "fixed"
|
||||
}
|
||||
],
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "affected",
|
||||
"value": "Premiere Pro:macOS",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"APSB25-87"
|
||||
],
|
||||
"credits": [],
|
||||
"cvssMetrics": [],
|
||||
"exploitKnown": false,
|
||||
"language": "en",
|
||||
"modified": null,
|
||||
"provenance": [
|
||||
{
|
||||
"source": "vndr-adobe",
|
||||
"kind": "parser",
|
||||
"value": "APSB25-87",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
}
|
||||
],
|
||||
"published": "2025-09-08T00:00:00+00:00",
|
||||
"references": [
|
||||
{
|
||||
"kind": "advisory",
|
||||
"provenance": {
|
||||
"source": "vndr-adobe",
|
||||
"kind": "parser",
|
||||
"value": "APSB25-87",
|
||||
"decisionReason": null,
|
||||
"recordedAt": "2025-09-10T00:00:00+00:00",
|
||||
"fieldMask": []
|
||||
},
|
||||
"sourceTag": "adobe-psirt",
|
||||
"summary": "Date published: September 8, 2025",
|
||||
"url": "https://helpx.adobe.com/security/products/premiere_pro/apsb25-87.html"
|
||||
}
|
||||
],
|
||||
"severity": null,
|
||||
"summary": "Date published: September 8, 2025",
|
||||
"title": "APSB25-87: Security update available for Adobe Premiere Pro"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>APSB25-85</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>APSB25-85: Security update available for Adobe Acrobat Reader</h1>
|
||||
<p>Date published: September 9, 2025</p>
|
||||
|
||||
<h2>Affected Versions</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Product</td>
|
||||
<td>Track</td>
|
||||
<td>Affected Versions</td>
|
||||
<td>Platform</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Acrobat DC</td>
|
||||
<td>Continuous</td>
|
||||
<td>
|
||||
<p>Win - 25.001.20672 and earlier</p>
|
||||
<p>Mac - 25.001.20668 and earlier</p>
|
||||
</td>
|
||||
<td>Windows & macOS</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Acrobat Reader DC</td>
|
||||
<td>Continuous</td>
|
||||
<td>
|
||||
<p>Win - 25.001.20672 and earlier</p>
|
||||
<p>Mac - 25.001.20668 and earlier</p>
|
||||
</td>
|
||||
<td>Windows & macOS</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Updated Versions</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Product</td>
|
||||
<td>Track</td>
|
||||
<td>Updated Versions</td>
|
||||
<td>Platform</td>
|
||||
<td>Priority</td>
|
||||
<td>Availability</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Acrobat DC</td>
|
||||
<td>Continuous</td>
|
||||
<td>
|
||||
<p>Win - 25.001.20680</p>
|
||||
<p>Mac - 25.001.20678</p>
|
||||
</td>
|
||||
<td>Windows & macOS</td>
|
||||
<td>Priority 2</td>
|
||||
<td>Available</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Acrobat Reader DC</td>
|
||||
<td>Continuous</td>
|
||||
<td>
|
||||
<p>Win - 25.001.20680</p>
|
||||
<p>Mac - 25.001.20678</p>
|
||||
</td>
|
||||
<td>Windows & macOS</td>
|
||||
<td>Priority 2</td>
|
||||
<td>Available</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>APSB25-87</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>APSB25-87: Security update available for Adobe Premiere Pro</h1>
|
||||
<p>Date published: September 8, 2025</p>
|
||||
|
||||
<h2>Affected Versions</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Product</td>
|
||||
<td>Track</td>
|
||||
<td>Affected Versions</td>
|
||||
<td>Platform</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Premiere Pro</td>
|
||||
<td>Quarterly</td>
|
||||
<td>
|
||||
<p>Win - 24.5 and earlier</p>
|
||||
<p>Mac - 24.5 and earlier</p>
|
||||
</td>
|
||||
<td>Windows & macOS</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Updated Versions</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Product</td>
|
||||
<td>Track</td>
|
||||
<td>Updated Versions</td>
|
||||
<td>Platform</td>
|
||||
<td>Priority</td>
|
||||
<td>Availability</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Premiere Pro</td>
|
||||
<td>Quarterly</td>
|
||||
<td>
|
||||
<p>Win - 24.6</p>
|
||||
<p>Mac - 24.6</p>
|
||||
</td>
|
||||
<td>Windows & macOS</td>
|
||||
<td>Priority 3</td>
|
||||
<td>Available</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="/security/products/acrobat/apsb25-85.html">APSB25-85: Security update available for Adobe Acrobat Reader</a></td>
|
||||
<td>September 9, 2025</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/security/products/premiere_pro/apsb25-87.html">APSB25-87: Security update available for Adobe Premiere Pro</a></td>
|
||||
<td>09/08/2025</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Models/StellaOps.Concelier.Models.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Connector.Common/StellaOps.Concelier.Connector.Common.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Connector.Vndr.Adobe/StellaOps.Concelier.Connector.Vndr.Adobe.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Storage.Mongo/StellaOps.Concelier.Storage.Mongo.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Adobe/Fixtures/*.html" CopyToOutputDirectory="Always" TargetPath="Source/Vndr/Adobe/Fixtures/%(Filename)%(Extension)" />
|
||||
<None Include="Adobe/Fixtures/*.json" CopyToOutputDirectory="Always" TargetPath="Source/Vndr/Adobe/Fixtures/%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user