Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pages/api/[network]/add-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ async function handler(req, res) {
// Check API key
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
domain
domain,
network
);
if (!allowedApi) {
return res
Expand Down
3 changes: 2 additions & 1 deletion pages/api/[network]/claim-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ async function handler(req, res) {
// Check API key
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
domain
domain,
network
);
if (!allowedApi) {
return res
Expand Down
3 changes: 2 additions & 1 deletion pages/api/[network]/delete-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ async function handler(req, res) {
// Check API key
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
domain
domain,
network
);
if (!allowedApi) {
return res
Expand Down
5 changes: 3 additions & 2 deletions pages/api/[network]/delete-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ async function handler(req, res) {
}

// Check API key
const adminToken = await getAdminToken(req, body.domain);
const adminToken = await getAdminToken(req, body.domain, network);
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
body.domain
body.domain,
network
);
if (!allowedApi && !adminToken) {
return res
Expand Down
11 changes: 7 additions & 4 deletions pages/api/[network]/get-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,27 @@ const cors = Cors({
origin: "*",
});

async function checkApiKey(apiKey, domain) {
async function checkApiKey(apiKey, domain, network) {
if (!apiKey) {
return false;
}
let apiQuery;
if (!domain) {
apiQuery = await sql`
SELECT api_key.id, key FROM api_key
where api_key.key = ${apiKey}`;
join domain on api_key.domain_id = domain.id
where api_key.key = ${apiKey}
and domain.network = ${network}`;
} else {
apiQuery = await sql`
SELECT api_key.id, key FROM api_key
join domain
on api_key.domain_id = domain.id
where domain.name = ${domain}
and domain.network = ${network}
and api_key.key = ${apiKey}`;
}
if (apiQuery.count >= 1) {
if (apiQuery.length >= 1) {
return true;
}
return false;
Expand Down Expand Up @@ -64,7 +67,7 @@ async function handler(req, res) {
const apiKey = headers.authorization || req.query.api_key;
// Check API key

const allowedApi = await checkApiKey(apiKey, domain);
const allowedApi = await checkApiKey(apiKey, domain, network);
// if apiKey exists and is not allowed, return 401
if (apiKey && !allowedApi) {
return res.status(401).json({ error: "Unauthorized" });
Expand Down
80 changes: 80 additions & 0 deletions pages/api/[network]/get-names.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe("get-names API E2E", () => {
mainnet: {},
sepolia: {},
};
let sharedDomainIds = {};

beforeAll(async () => {
await setupTestDatabase();
Expand Down Expand Up @@ -172,6 +173,22 @@ describe("get-names API E2E", () => {
}
});

afterEach(async () => {
if (sharedDomainIds.mainnet || sharedDomainIds.sepolia) {
await sqlForTests`DELETE FROM subdomain_text_record WHERE subdomain_id IN (
SELECT id FROM subdomain WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})
)`;
await sqlForTests`DELETE FROM subdomain_coin_type WHERE subdomain_id IN (
SELECT id FROM subdomain WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})
)`;
await sqlForTests`DELETE FROM subdomain WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
await sqlForTests`DELETE FROM api_key WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
await sqlForTests`DELETE FROM brand WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
await sqlForTests`DELETE FROM domain WHERE id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
sharedDomainIds = {};
}
});

afterAll(async () => {
/**
* Test Data Cleanup:
Expand Down Expand Up @@ -203,6 +220,69 @@ describe("get-names API E2E", () => {
await teardownTestDatabase();
});

describe("Same domain name stays scoped to the selected network", () => {
const sharedDomain = "shared-list.eth";
const mainnetKey = "shared-list-mainnet-key";
const sepoliaKey = "shared-list-sepolia-key";

beforeEach(async () => {
const [mainnetDomain] = await sqlForTests`
INSERT INTO domain (name, network)
VALUES (${sharedDomain}, 'mainnet')
RETURNING id
`;
const [sepoliaDomain] = await sqlForTests`
INSERT INTO domain (name, network)
VALUES (${sharedDomain}, 'sepolia')
RETURNING id
`;

sharedDomainIds = {
mainnet: mainnetDomain.id,
sepolia: sepoliaDomain.id,
};

await sqlForTests`
INSERT INTO api_key (domain_id, key)
VALUES (${mainnetDomain.id}, ${mainnetKey}),
(${sepoliaDomain.id}, ${sepoliaKey})
`;

await sqlForTests`
INSERT INTO brand (domain_id, share_with_data_providers)
VALUES (${mainnetDomain.id}, false),
(${sepoliaDomain.id}, false)
`;

await sqlForTests`
INSERT INTO subdomain (domain_id, name, address)
VALUES (${mainnetDomain.id}, ${`main.${sharedDomain}`}, ${TEST_ADDRESSES[1]}),
(${sepoliaDomain.id}, ${`sepolia.${sharedDomain}`}, ${TEST_ADDRESSES[2]})
`;
});

test("getNames_sameDomainDifferentNetworkKey_returns401", async () => {
const req = createRequest({
method: "GET",
query: {
network: "public_v1",
domain: sharedDomain,
},
headers: {
authorization: sepoliaKey,
},
});
const res = createResponse();

await handler(req, res);

expect(res._getStatusCode()).toBe(401);
expect(JSON.parse(res._getData())).toEqual({
error: "Unauthorized",
});
});
});

/**
* Tests network validation:
* - Empty network parameter returns 400
Expand Down
3 changes: 2 additions & 1 deletion pages/api/[network]/revoke-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ async function handler(req, res) {
// Check API key
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
body.domain
body.domain,
network
);
if (!allowedApi) {
return res
Expand Down
5 changes: 3 additions & 2 deletions pages/api/[network]/search-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ async function handler(req, res) {
// Check API key
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
domain
domain,
network
);
const adminToken = await getAdminToken(req, domain);
const adminToken = await getAdminToken(req, domain, network);
if (!allowedApi && !adminToken) {
return res.status(401).json({
error: "key error - You are not authorized to use this endpoint",
Expand Down
4 changes: 2 additions & 2 deletions pages/api/[network]/set-domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async function handler(req, res) {
.json({ error: "Domain does not exist. Please use /enable-domain." });
}

const allowedApi = await checkApiKey(apiKey, domainName);
const allowedApi = await checkApiKey(apiKey, domainName, network);
if (!allowedApi) {
return res
.status(401)
Expand Down Expand Up @@ -91,7 +91,7 @@ async function handler(req, res) {
"contenthash",
"contenthash_raw"
)}
where name = ${domainName}
where id = ${domainQuery[0].id}
returning id;`;

// Delete existing text records
Expand Down
76 changes: 76 additions & 0 deletions pages/api/[network]/set-domain.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,91 @@ const SUPPORTED_NETWORKS = [

describe("set-domain API E2E", () => {
let testDomainId;
let sharedDomainIds = {};

beforeAll(async () => {
await setupTestDatabase();
});

afterEach(async () => {
if (sharedDomainIds.mainnet || sharedDomainIds.sepolia) {
await sqlForTests`DELETE FROM domain_coin_type WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
await sqlForTests`DELETE FROM domain_text_record WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
await sqlForTests`DELETE FROM api_key WHERE domain_id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
await sqlForTests`DELETE FROM domain WHERE id IN (${sharedDomainIds.mainnet || 0}, ${sharedDomainIds.sepolia || 0})`;
sharedDomainIds = {};
}
});

afterAll(async () => {
await teardownTestDatabase();
});

describe("Same domain name stays scoped to the selected network", () => {
const sharedDomain = "shared-domain.eth";
const mainnetKey = "shared-domain-mainnet-key";
const sepoliaKey = "shared-domain-sepolia-key";
const originalMainnetAddress = "0x1111111111111111111111111111111111111111";
const originalSepoliaAddress = "0x2222222222222222222222222222222222222222";

beforeEach(async () => {
const [mainnetDomain] = await sqlForTests`
INSERT INTO domain (name, network, address)
VALUES (${sharedDomain}, 'mainnet', ${originalMainnetAddress})
RETURNING id
`;
const [sepoliaDomain] = await sqlForTests`
INSERT INTO domain (name, network, address)
VALUES (${sharedDomain}, 'sepolia', ${originalSepoliaAddress})
RETURNING id
`;

sharedDomainIds = {
mainnet: mainnetDomain.id,
sepolia: sepoliaDomain.id,
};

await sqlForTests`
INSERT INTO api_key (domain_id, key)
VALUES (${mainnetDomain.id}, ${mainnetKey}),
(${sepoliaDomain.id}, ${sepoliaKey})
`;
});

test("setDomain_updatesOnlyTheSelectedNetwork", async () => {
const updatedMainnetAddress =
"0x9999999999999999999999999999999999999999";
const req = createRequest({
method: "POST",
headers: {
authorization: mainnetKey,
},
query: {
network: "public_v1",
},
body: {
domain: sharedDomain,
address: updatedMainnetAddress,
},
});
const response = createResponse();

await handler(req, response);

expect(response._getStatusCode()).toBe(200);

const [mainnetDomain] = await sqlForTests`
SELECT address FROM domain WHERE id = ${sharedDomainIds.mainnet}
`;
const [sepoliaDomain] = await sqlForTests`
SELECT address FROM domain WHERE id = ${sharedDomainIds.sepolia}
`;

expect(mainnetDomain.address).toBe(updatedMainnetAddress);
expect(sepoliaDomain.address).toBe(originalSepoliaAddress);
});
});

/**
* Tests network validation:
* - Empty network parameter
Expand Down
3 changes: 2 additions & 1 deletion pages/api/[network]/set-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ async function handler(req, res) {
// Check API key
const allowedApi = await checkApiKey(
headers.authorization || req.query.api_key,
body.domain
body.domain,
network
);
if (!allowedApi) {
return res
Expand Down
Loading