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