chore: Update golangci-lint configuration and Makefile for WASM build process
cognitive committed
Jan 27, 2026 at 11:39 UTC
bbe544b345fbc120b0af958e068f92426c66aa1b
10 files changed
+138
-138
.pre-commit-config.yaml
+7
-7
@@ -21,6 +21,13 @@ repos:
21
- repo: https://github.com/golangci/golangci-lint
22
rev: v2.6.2
23
hooks:
24
+ - id: golangci-lint-config-verify
25
+ name: golangci-lint-config-verify
26
+ description: Verifies the configuration file
27
+ entry: golangci-lint config verify
28
+ files: '\.golangci\.(?:yml|yaml|toml|json)'
29
+ language: golang
30
+ pass_filenames: false
31
- id: golangci-lint
32
name: golangci-lint
33
description: Fast linters runner for Go. Note that only modified files are linted, so linters like 'unused' that need to scan all files won't work as expected.
@@ -45,10 +52,3 @@ repos:
52
language: golang
53
require_serial: true
54
pass_filenames: false
48
- - id: golangci-lint-config-verify
49
- name: golangci-lint-config-verify
50
- description: Verifies the configuration file
51
- entry: golangci-lint config verify
52
- files: '\.golangci\.(?:yml|yaml|toml|json)'
53
- language: golang
54
- pass_filenames: false
Makefile
+3
-3
@@ -61,7 +61,7 @@ build-wasm:
61
@echo "[wasm] building webclient WASM..."
62
@mkdir -p cmd/relay-server/dist/wasm
63
GOOS=js GOARCH=wasm go build -trimpath -ldflags "-s -w" -o cmd/relay-server/dist/wasm/portal.wasm ./cmd/webclient
64
-
64
+
65
@echo "[wasm] optimizing with wasm-opt..."
66
@if command -v wasm-opt >/dev/null 2>&1; then \
67
wasm-opt -Oz --enable-bulk-memory cmd/relay-server/dist/wasm/portal.wasm -o cmd/relay-server/dist/wasm/portal.wasm.tmp && \
@@ -71,7 +71,7 @@ build-wasm:
71
echo "[wasm] WARNING: wasm-opt not found, skipping optimization"; \
72
echo "[wasm] Install binaryen for smaller WASM files: brew install binaryen (macOS) or apt-get install binaryen (Linux)"; \
73
fi
74
-
74
+
75
@echo "[wasm] calculating SHA256 hash..."
76
@WASM_HASH=$$(shasum -a 256 cmd/relay-server/dist/wasm/portal.wasm | awk '{print $$1}'); \
77
echo "[wasm] SHA256: $$WASM_HASH"; \
@@ -80,7 +80,7 @@ build-wasm:
80
cp cmd/relay-server/dist/wasm/portal.wasm cmd/relay-server/dist/wasm/$$WASM_HASH.wasm; \
81
rm -f cmd/relay-server/dist/wasm/portal.wasm; \
82
echo "[wasm] content-addressed WASM: dist/wasm/$$WASM_HASH.wasm"
83
-
83
+
84
@echo "[wasm] copying additional resources..."
85
@cp cmd/webclient/wasm_exec.js cmd/relay-server/dist/wasm/wasm_exec.js
86
@cp cmd/webclient/service-worker.js cmd/relay-server/dist/wasm/service-worker.js
buf.gen.yaml
+1
-1
@@ -9,4 +9,4 @@ plugins:
9
out: .
10
opt: paths=source_relative
11
inputs:
12
- - directory: proto
\ No newline at end of file
12
+ - directory: proto
cmd/portal-tunnel/README.md
+1
-1
@@ -20,7 +20,7 @@ You can run the tunnel using command-line flags or a configuration file.
20
## Flags
21
22
```text
23
-Usage:
23
+Usage:
24
portal-tunnel [OPTIONS] [ARGUMENTS]
25
26
Options:
cmd/relay-server/frontend/public/favicon.svg
+1
-1
@@ -1,3 +1,3 @@
1
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1554" height="2500"><svg xmlns="http://www.w3.org/2000/svg" width="1554" height="2500" viewBox="0 0 906.26 1457.543"><path fill="#17C0E9" d="M254.854 137.158c-34.46 84.407-88.363 149.39-110.934 245.675 90.926-187.569 308.397-483.654 554.729-348.685 135.487 74.216 194.878 270.78 206.058 467.566 21.924 385.996-190.977 853.604-467.585 943.057-174.879 56.543-307.375-86.447-364.527-198.115-176.498-344.82 2.041-910.077 182.259-1109.498zm198.13 7.918C202.61 280.257 4.622 968.542 207.322 1270.414c51.713 77.029 194.535 160.648 285.294 71.318-209.061 31.529-288.389-176.143-301.145-340.765 31.411 147.743 139.396 326.12 309.075 253.588 251.957-107.723 376.778-648.46 269.433-966.817 22.394 134.616 15.572 317.711-47.551 412.087 86.655-230.615 7.903-704.478-269.444-554.749z"></path></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
2
@media (prefers-color-scheme: dark) { :root { filter: none; } }
3
-</style></svg>
\ No newline at end of file
3
+</style></svg>
cmd/vanity-id/README.md
+1
-1
@@ -114,4 +114,4 @@ if err != nil {
114
}
115
116
// Verify the ID matches
117
-fmt.Println(cred.ID()) // Should print: TESTIWIBIRNDLZOHD3H2D6AD7Q
\ No newline at end of file
117
+fmt.Println(cred.ID()) // Should print: TESTIWIBIRNDLZOHD3H2D6AD7Q
cmd/webclient/wasm_exec.js
+4
-4
@@ -2,11 +2,11 @@
2
// Use of this source code is governed by a BSD-style
3
//
4
// Copyright 2009 The Go Authors.
5
-//
5
+//
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are
8
// met:
9
-//
9
+//
10
// * Redistributions of source code must retain the above copyright
11
// notice, this list of conditions and the following disclaimer.
12
// * Redistributions in binary form must reproduce the above
@@ -16,7 +16,7 @@
16
// * Neither the name of Google LLC nor the names of its
17
// contributors may be used to endorse or promote products derived from
18
// this software without specific prior written permission.
19
-//
19
+//
20
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -601,4 +601,4 @@
601
};
602
}
603
}
604
-})();
\ No newline at end of file
604
+})();
docs/architecture.md
+99
-99
@@ -1,99 +1,99 @@
1
-
2
-# Architecture
3
-
4
-## System Architecture
5
-
6
-```mermaid
7
-graph TB
8
- subgraph "Client A"
9
- CA[Client A]
10
- CA --> CA_ID[Identity: Ed25519]
11
- CA --> CA_LEASE[Lease Manager]
12
- end
13
-
14
- subgraph "Client B"
15
- CB[Client B]
16
- CB --> CB_ID[Identity: Ed25519]
17
- CB --> CB_LEASE[Lease Manager]
18
- end
19
-
20
- subgraph "Relay Server"
21
- RS[Relay Server]
22
- RS --> RS_ID[Server Identity]
23
- RS --> LM[Lease Manager]
24
- RS --> CM[Connection Manager]
25
- RS --> FH[Forwarding Handler]
26
- end
27
-
28
- CA -.->|1. Register Lease| RS
29
- CB -.->|2. Register Lease| RS
30
- CB -.->|3. Request Connection| RS
31
- RS -.->|4. Forward Request| CA
32
- CA -.->|5. Accept Connection| RS
33
- RS -.->|6. Establish E2EE| CB
34
-
35
- CA <-->|7. Encrypted Data| CB
36
-```
37
-
38
-## Component Architecture
39
-
40
-```mermaid
41
-graph LR
42
- subgraph "Client Components"
43
- C[RelayClient]
44
- C --> H[Handshaker]
45
- C --> LM[LeaseManager]
46
- C --> SC[SecureConnection]
47
- end
48
-
49
- subgraph "Server Components"
50
- S[RelayServer]
51
- S --> LH[LeaseHandler]
52
- S --> CH[ConnectionHandler]
53
- S --> FH[ForwardingHandler]
54
- S --> LM2[LeaseManager]
55
- end
56
-
57
- subgraph "Crypto Operations"
58
- CO[CryptoOps]
59
- CO --> CRED[Credential]
60
- CO --> SIG[Signature]
61
- CO --> E2EE[End-to-End Encryption]
62
- end
63
-
64
- C <-->|Protocol Messages| S
65
- H --> CO
66
- SC --> CO
67
- LH --> LM2
68
- CH --> FH
69
-```
70
-
71
-## Connection Flow
72
-
73
-```mermaid
74
-sequenceDiagram
75
- participant C1 as Client 1
76
- participant RS as Relay Server
77
- participant C2 as Client 2
78
-
79
- Note over C1,C2: Lease Registration Phase
80
- C1->>RS: Register Lease (Identity, ALPN)
81
- RS->>C1: Lease Confirmation
82
-
83
- C2->>RS: Register Lease (Identity, ALPN)
84
- RS->>C2: Lease Confirmation
85
-
86
- Note over C1,C2: Connection Establishment Phase
87
- C2->>RS: Request Connection (to Client 1)
88
- RS->>C1: Forward Connection Request
89
- C1->>RS: Accept Connection
90
- RS->>C2: Connection Accepted
91
-
92
- Note over C1,C2: Secure Handshake Phase
93
- C2->>C1: X25519 Handshake (via relay)
94
- C1->>C2: X25519 Response (via relay)
95
-
96
- Note over C1,C2: End-to-End Encrypted Communication
97
- C2->>C1: Encrypted Data (ChaCha20-Poly1305)
98
- C1->>C2: Encrypted Data (ChaCha20-Poly1305)
99
-```
1
+
2
+# Architecture
3
+
4
+## System Architecture
5
+
6
+```mermaid
7
+graph TB
8
+ subgraph "Client A"
9
+ CA[Client A]
10
+ CA --> CA_ID[Identity: Ed25519]
11
+ CA --> CA_LEASE[Lease Manager]
12
+ end
13
+
14
+ subgraph "Client B"
15
+ CB[Client B]
16
+ CB --> CB_ID[Identity: Ed25519]
17
+ CB --> CB_LEASE[Lease Manager]
18
+ end
19
+
20
+ subgraph "Relay Server"
21
+ RS[Relay Server]
22
+ RS --> RS_ID[Server Identity]
23
+ RS --> LM[Lease Manager]
24
+ RS --> CM[Connection Manager]
25
+ RS --> FH[Forwarding Handler]
26
+ end
27
+
28
+ CA -.->|1. Register Lease| RS
29
+ CB -.->|2. Register Lease| RS
30
+ CB -.->|3. Request Connection| RS
31
+ RS -.->|4. Forward Request| CA
32
+ CA -.->|5. Accept Connection| RS
33
+ RS -.->|6. Establish E2EE| CB
34
+
35
+ CA <-->|7. Encrypted Data| CB
36
+```
37
+
38
+## Component Architecture
39
+
40
+```mermaid
41
+graph LR
42
+ subgraph "Client Components"
43
+ C[RelayClient]
44
+ C --> H[Handshaker]
45
+ C --> LM[LeaseManager]
46
+ C --> SC[SecureConnection]
47
+ end
48
+
49
+ subgraph "Server Components"
50
+ S[RelayServer]
51
+ S --> LH[LeaseHandler]
52
+ S --> CH[ConnectionHandler]
53
+ S --> FH[ForwardingHandler]
54
+ S --> LM2[LeaseManager]
55
+ end
56
+
57
+ subgraph "Crypto Operations"
58
+ CO[CryptoOps]
59
+ CO --> CRED[Credential]
60
+ CO --> SIG[Signature]
61
+ CO --> E2EE[End-to-End Encryption]
62
+ end
63
+
64
+ C <-->|Protocol Messages| S
65
+ H --> CO
66
+ SC --> CO
67
+ LH --> LM2
68
+ CH --> FH
69
+```
70
+
71
+## Connection Flow
72
+
73
+```mermaid
74
+sequenceDiagram
75
+ participant C1 as Client 1
76
+ participant RS as Relay Server
77
+ participant C2 as Client 2
78
+
79
+ Note over C1,C2: Lease Registration Phase
80
+ C1->>RS: Register Lease (Identity, ALPN)
81
+ RS->>C1: Lease Confirmation
82
+
83
+ C2->>RS: Register Lease (Identity, ALPN)
84
+ RS->>C2: Lease Confirmation
85
+
86
+ Note over C1,C2: Connection Establishment Phase
87
+ C2->>RS: Request Connection (to Client 1)
88
+ RS->>C1: Forward Connection Request
89
+ C1->>RS: Accept Connection
90
+ RS->>C2: Connection Accepted
91
+
92
+ Note over C1,C2: Secure Handshake Phase
93
+ C2->>C1: X25519 Handshake (via relay)
94
+ C1->>C2: X25519 Response (via relay)
95
+
96
+ Note over C1,C2: End-to-End Encrypted Communication
97
+ C2->>C1: Encrypted Data (ChaCha20-Poly1305)
98
+ C1->>C2: Encrypted Data (ChaCha20-Poly1305)
99
+```
docs/development.md
+8
-8
@@ -1,18 +1,18 @@
1
# Development Principles and Operational Guide
2
3
-This document defines the core principles and operational scope of the Portal project.
3
+This document defines the core principles and operational scope of the Portal project.
4
It aims to prevent unnecessary feature expansion or direction drift, and to maintain a consistent user experience.
5
6
---
7
8
## 1. Usability Invariance Principle
9
-Portal developers must ensure that any new feature does not alter existing usability.
9
+Portal developers must ensure that any new feature does not alter existing usability.
10
A "change in usability" includes, but is not limited to:
11
12
-- Modifications to the Portal usage flow
13
-- Changes to the deployment or configuration process
14
-- Alterations to the SDK development environment
15
-- Increases in codebase complexity
12
+- Modifications to the Portal usage flow
13
+- Changes to the deployment or configuration process
14
+- Alterations to the SDK development environment
15
+- Increases in codebase complexity
16
- Any similar impacts that may affect the user experience
17
18
---
@@ -26,7 +26,7 @@ If a feature impacts usability, the proposer must provide a clear written ration
26
27
28
## 3. Testing and Quality Assurance
29
-Unfinished or experimental features must not be merged directly into the main branch.
29
+Unfinished or experimental features must not be merged directly into the main branch.
30
All new features must be fully tested and verified in a personal branch before merging.
31
32
---
@@ -34,7 +34,7 @@ All new features must be fully tested and verified in a personal branch before m
34
## 4. Project Philosophy and Scope
35
Portal serves as a relay layer that allows individuals to publicly expose locally running services, with built-in end-to-end encryption.
36
37
-- When proposing new features, include sufficient justification and follow the agreement process described above.
37
+- When proposing new features, include sufficient justification and follow the agreement process described above.
38
- Approved features must be documented and tracked in the project roadmap.
39
40
---
portal/core/cryptoops/README.md
+13
-13
@@ -140,12 +140,12 @@ Parameters:
140
```go
141
payloadBytes := proto.Marshal(clientInitPayload)
142
signature := ed25519.Sign(clientPrivateKey, payloadBytes)
143
-
143
+
144
signedPayload := &SignedPayload{
145
Data: payloadBytes,
146
Signature: signature,
147
}
148
-
148
+
149
// Send length-prefixed message (4 bytes length + data)
150
writeLengthPrefixed(conn, proto.Marshal(signedPayload))
151
```
@@ -159,7 +159,7 @@ Parameters:
159
- Verify ALPN matches expected value(s)
160
- Validate identity structure (correct key sizes)
161
- Verify Ed25519 signature using client's public key
162
-
162
+
163
**Security Note**: If validation fails, server closes connection silently (no error response) to prevent information leakage.
164
165
2. **Generate Server Ephemeral Keypair**
@@ -259,15 +259,15 @@ This prevents excessive memory allocation while maintaining compatibility with t
259
func (sc *SecureConnection) Write(p []byte) (int, error) {
260
// 1. Generate random nonce
261
nonce := randomBytes(12)
262
-
262
+
263
// 2. Encrypt with AEAD
264
ciphertext := encryptor.Seal(nil, nonce, plaintext, nil)
265
// ciphertext = encrypted_data || tag
266
-
266
+
267
// 3. Frame: length + nonce + ciphertext
268
length := len(nonce) + len(ciphertext)
269
frame := length (4 bytes) || nonce || ciphertext
270
-
270
+
271
// 4. Write to connection
272
conn.Write(frame)
273
}
@@ -280,23 +280,23 @@ func (sc *SecureConnection) Read(p []byte) (int, error) {
280
// 1. Read 4-byte length prefix
281
lengthBytes := readFull(4)
282
length := binary.BigEndian.Uint32(lengthBytes)
283
-
283
+
284
// 2. Validate size limit
285
if length > maxRawPacketSize {
286
return error
287
}
288
-
288
+
289
// 3. Read encrypted message
290
msgBytes := readFull(length)
291
nonce := msgBytes[0:12]
292
ciphertext := msgBytes[12:]
293
-
293
+
294
// 4. Decrypt and authenticate
295
plaintext, err := decryptor.Open(nil, nonce, ciphertext, nil)
296
if err != nil {
297
return ErrDecryptionFailed // Authentication failed
298
}
299
-
299
+
300
// 5. Copy to output buffer
301
copy(p, plaintext)
302
}
@@ -481,7 +481,7 @@ const (
481
sessionKeySize = 32 // 256-bit symmetric keys
482
maxTimestampSkew = 30 * time.Second // Clock skew tolerance
483
maxRawPacketSize = 1 << 26 // 64MB - matches relay server
484
-
484
+
485
// Key derivation context strings
486
clientKeyInfo = "RDSEC_KEY_CLIENT"
487
serverKeyInfo = "RDSEC_KEY_SERVER"
@@ -506,7 +506,7 @@ func (sc *SecureConnection) Read(p []byte) (int, error) {
506
sc.readBuffer.B = sc.readBuffer.B[:len(sc.readBuffer.B)-n]
507
return n, nil
508
}
509
-
509
+
510
// Otherwise, decrypt new packet...
511
}
512
```
@@ -584,4 +584,4 @@ When testing this implementation:
584
- HKDF-SHA256 key derivation
585
- Timestamp-based replay protection
586
- ALPN support
587
-- Automatic message fragmentation
\ No newline at end of file
587
+- Automatic message fragmentation