Skip to content

Commit 057ba4a

Browse files
committed
fix: make verify endpoint working
1 parent bb17a4b commit 057ba4a

14 files changed

Lines changed: 187 additions & 84 deletions

bin/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void main(List<String> args) async {
6363
server.serverHeader = 'Echidna License Server';
6464
server.defaultResponseHeaders.contentType = ContentType.json;
6565

66-
server.handleError((e, s) {
66+
server.handleError((Object e, StackTrace s) {
6767
Logger.root.severe('Failed to handle request', e, s);
6868
});
6969

lib/modules/admin/presentation/handlers/create_client_key_handler.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Future<Response> createClientKeyHandler(Request request, Injector i, ModularArgu
5656
}
5757

5858
try {
59-
final uuid = i.get<Uuid>();
59+
const uuid = Uuid();
6060

6161
final key = uuid.v4();
6262

lib/modules/admin/presentation/handlers/create_license_handler.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ Future<Response> createLicenseHandler(Request request, Injector i, ModularArgume
3030
return Response.badRequest(body: 'Product with ID $productId does not exist.');
3131
}
3232

33-
final uuid = i.get<Uuid>();
33+
const uuid = Uuid();
3434

35-
if (await prisma.license.findUnique(
36-
where: LicenseWhereUniqueInput(
35+
if (await prisma.license.findFirst(
36+
where: LicenseWhereInput(
3737
userId: PrismaUnion.$2(
3838
userId != null ? PrismaUnion.$1(userId) : const PrismaUnion.$2(PrismaNull()),
3939
),

lib/modules/client/infra/datasources/std_license_status_datasource.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ class StdLicenseStatusDatasource extends LicenseStatusDatasource {
99
/// Standard implementation of [LicenseStatusDatasource].
1010
StdLicenseStatusDatasource(this.prisma);
1111

12-
@override
13-
void dispose() {}
14-
1512
@override
1613
Future<dto.LicenseStatus> getLicenseStatus(String licenseKey) async {
1714
final license = await prisma.license.findUnique(

lib/modules/client/infra/services/hmac_signature_service.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ class HmacSignatureService extends SignatureService {
1212
/// Signs and verifies signatures using the HMAC algorithm.
1313
HmacSignatureService(this.prisma);
1414

15-
@override
16-
void dispose() {}
17-
1815
@override
1916
String sign(String body, String secret) {
2017
final hmac = Hmac(sha256, utf8.encode(secret));

lib/modules/client/presentation/guards/signature_guard.dart

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:async';
2+
import 'dart:convert';
23

34
import 'package:echidna_server/echidna_server.dart';
45
import 'package:echidna_server/modules/client/client.dart';
@@ -8,32 +9,38 @@ import 'package:shelf_modular/shelf_modular.dart';
89
/// Verifies that the client key is valid.
910
class SignatureGuard extends RouteGuard {
1011
@override
11-
FutureOr<bool> canActivate(Request request, Route route) async {
12-
final clientId = int.tryParse(request.headers['client-id'] ?? '');
13-
14-
if (clientId == null) {
15-
return false;
16-
}
12+
FutureOr<bool> canActivate(Request request, [ModularRoute? route]) async {
13+
final body = await request.readAsString();
1714

1815
final signatureService = Modular.get<SignatureService>();
1916

2017
final clientKey = await signatureService.extractClientKey(request);
2118

22-
if (clientKey == null) {
23-
return false;
24-
}
19+
print(request.headers);
20+
21+
if (clientKey == null) return false;
22+
23+
print('Client key: ${clientKey.key}');
2524

2625
final signature = request.headers['x-signature'];
2726

28-
if (signature == null) {
29-
return false;
30-
}
27+
if (signature == null) return false;
28+
29+
print('Signature: $signature');
3130

32-
return signatureService.verifySignature(
33-
signature,
34-
await request.readAsString(),
35-
clientKey.key!,
36-
);
31+
return signatureService.verifySignature(signature, body, clientKey.key!);
32+
}
33+
34+
@override
35+
FutureOr<Response> Function(Request p1) call(Handler handler, [ModularRoute? route]) {
36+
return (request) async {
37+
if (!await canActivate(request, route! as Route)) {
38+
return Response.forbidden(
39+
jsonEncode({'error': 'Invalid signature'}),
40+
);
41+
}
42+
return handler(request);
43+
};
3744
}
3845
}
3946

@@ -48,24 +55,21 @@ class SignatureMiddleware extends ModularMiddleware {
4855

4956
final signatureService = Modular.get<SignatureService>();
5057

51-
final clientId = int.tryParse(request.headers['client-id'] ?? '');
52-
53-
if (clientId == null) {
54-
return response;
55-
}
56-
5758
final clientKey = await signatureService.extractClientKey(request);
5859

5960
if (clientKey == null) {
6061
return response;
6162
}
6263

64+
final body = await response.readAsString();
65+
6366
final signature = signatureService.sign(
64-
await response.readAsString(),
67+
body,
6568
clientKey.key!,
6669
);
6770

6871
return response.change(
72+
body: body,
6973
headers: {
7074
'x-signature': signature,
7175
},

lib/modules/client/presentation/handlers/verify_license_handler.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ Future<Response> verifyLicenseHandler(Request request, Injector i, ModularArgume
1414

1515
if (clientKey == null) {
1616
request.log('Could not extract client key. Unauthorized.');
17-
return Response.forbidden('Invalid client key');
17+
return Response.forbidden('Invalid signature');
1818
}
1919

20-
final userId = args.params['user-id'];
20+
final userId = args.data['userId'];
2121

2222
if (userId == null) {
2323
request.log('Bad Request: No user ID given');
2424
return Response.badRequest();
2525
}
2626

27-
var license = await prisma.license.findUnique(
28-
where: LicenseWhereUniqueInput(
29-
userId: PrismaUnion.$1(userId),
27+
var license = await prisma.license.findFirst(
28+
where: LicenseWhereInput(
29+
userId: PrismaUnion.$2(PrismaUnion.$1(userId)),
3030
customerId: PrismaUnion.$2(clientKey.customerId!),
3131
productId: PrismaUnion.$2(clientKey.productId!),
3232
),
@@ -41,17 +41,17 @@ Future<Response> verifyLicenseHandler(Request request, Injector i, ModularArgume
4141
i,
4242
ModularArguments(
4343
uri: args.uri,
44-
params: {
44+
data: {
4545
'customerId': clientKey.customerId,
4646
'productId': clientKey.productId,
4747
'userId': userId,
4848
},
4949
),
5050
);
5151

52-
license = await prisma.license.findUnique(
53-
where: LicenseWhereUniqueInput(
54-
userId: PrismaUnion.$1(userId),
52+
license = await prisma.license.findFirst(
53+
where: LicenseWhereInput(
54+
userId: PrismaUnion.$2(PrismaUnion.$1(userId)),
5555
customerId: PrismaUnion.$2(clientKey.customerId!),
5656
productId: PrismaUnion.$2(clientKey.productId!),
5757
),

lib/modules/server/server.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ class ServerModule extends Module {
4242
'/verify',
4343
module: ClientModule(prisma),
4444
middlewares: [
45-
SignatureGuard(),
45+
// idk why but the order of these middlewares is reversed
46+
// and we want the SignatureGuard to be the first one to run
4647
SignatureMiddleware(),
48+
SignatureGuard(),
4749
],
4850
);
4951
}

0 commit comments

Comments
 (0)