-
-
Notifications
You must be signed in to change notification settings - Fork 0
chore: better token middleware + format #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
a3c7439
add analysis
gocanto d283f47
start working on pahse 1
gocanto 0731657
phase II
gocanto 8ae6ed6
extract ttl_cache
gocanto 81d21a7
extract portal pkg
gocanto 3109ca2
extract limiter
gocanto 8c6a035
format
gocanto 72c3101
remove nested package
gocanto b62d7db
extract valid_timestamp
gocanto 3cc9bb8
format
gocanto 02b6f8d
tests
gocanto fd1f6a7
format
gocanto 3184543
more tests
gocanto 6c1adf1
token integration tests
gocanto 1b1c938
wip
gocanto 6846502
wip
gocanto d59250f
wip
gocanto 2e61b42
wip
gocanto 942b14b
add progress
gocanto 2baa42f
wip
gocanto 4412089
wip
gocanto b4ce019
extract ReadWithSizeLimit
gocanto bbaf94c
format
gocanto 9121f8a
headers
gocanto 5049a4f
better abstraction
gocanto 29923d6
wip
gocanto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
docs/middleware/postman/token-local.postman_collection.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| { | ||
| "info": { | ||
| "name": "Oullin API — Token Auth (Local)", | ||
| "description": "Postman collection for calling protected endpoints locally via Caddy (http://localhost:8080). It uses a collection-level pre-request script to compute the required X-API-* headers and signature.", | ||
| "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", | ||
| "_postman_id": "5d8d0a1a-7a1e-4f6e-b2f2-9d2a0a8f0c11" | ||
| }, | ||
| "item": [ | ||
| { | ||
| "name": "List posts (POST /posts)", | ||
| "request": { | ||
| "method": "POST", | ||
| "header": [ | ||
| { "key": "Content-Type", "value": "application/json" } | ||
| ], | ||
| "url": { | ||
| "raw": "{{baseUrl}}/posts", | ||
| "host": ["{{baseUrl}}"], | ||
| "path": ["posts"] | ||
| }, | ||
| "body": { | ||
| "mode": "raw", | ||
| "raw": "{}" | ||
| }, | ||
| "description": "List or filter posts. Requires signed headers generated by the collection pre-request script." | ||
| }, | ||
| "response": [] | ||
| }, | ||
| { | ||
| "name": "Show post (GET /posts/hello)", | ||
| "request": { | ||
| "method": "GET", | ||
| "header": [], | ||
| "url": { | ||
| "raw": "{{baseUrl}}/posts/hello", | ||
| "host": ["{{baseUrl}}"], | ||
| "path": ["posts", "hello"] | ||
| }, | ||
| "description": "Fetch a single post by slug (example: hello)." | ||
| }, | ||
| "response": [] | ||
| } | ||
| ], | ||
| "event": [ | ||
| { | ||
| "listen": "prerequest", | ||
| "script": { | ||
| "type": "text/javascript", | ||
| "exec": [ | ||
| "(function() {", | ||
| " // CryptoJS available in Postman sandbox", | ||
| " const crypto = require('crypto-js');", | ||
| " function sha256Hex(str) { return crypto.SHA256(str || '').toString(crypto.enc.Hex); }", | ||
| " function sortedQuery(u) {", | ||
| " const url = new URL(u);", | ||
| " const keys = Array.from(url.searchParams.keys());", | ||
| " keys.sort();", | ||
| " const parts = [];", | ||
| " for (const k of keys) {", | ||
| " const vs = url.searchParams.getAll(k).sort();", | ||
| " for (const v of vs) parts.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));", | ||
| " }", | ||
| " return parts.join('&');", | ||
| " }", | ||
| " const method = pm.request.method.toUpperCase();", | ||
| " const urlStr = pm.environment.get('baseUrl') + pm.request.url.getPathWithQuery();", | ||
| " const urlObj = new URL(urlStr);", | ||
| " const path = urlObj.pathname;", | ||
| " const query = sortedQuery(urlStr);", | ||
| " const username = pm.environment.get('username');", | ||
| " const publicKey = pm.environment.get('publicKey');", | ||
| " const secretKey = pm.environment.get('secretKey');", | ||
| " const timestamp = Math.floor(Date.now() / 1000).toString();", | ||
| " const nonce = crypto.lib.WordArray.random(16).toString();", | ||
| " const body = (method === 'GET' || method === 'DELETE') ? '' : (pm.request.body && pm.request.body.raw || '');", | ||
| " const bodyHash = sha256Hex(body);", | ||
| " const canonical = [method, path, query, username, publicKey, timestamp, nonce, bodyHash].join('\n');", | ||
| " const signature = crypto.HmacSHA256(canonical, secretKey).toString();", | ||
| " pm.request.headers.upsert({ key: 'X-Request-ID', value: pm.environment.get('requestId') || nonce });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Username', value: username });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Key', value: publicKey });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Timestamp', value: timestamp });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Nonce', value: nonce });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Signature', value: signature });", | ||
| "})();" | ||
| ] | ||
| } | ||
| } | ||
| ], | ||
| "variable": [ | ||
| { "key": "baseUrl", "value": "http://localhost:8080", "type": "string" }, | ||
| { "key": "username", "value": "", "type": "string" }, | ||
| { "key": "publicKey", "value": "", "type": "string" }, | ||
| { "key": "secretKey", "value": "", "type": "string" }, | ||
| { "key": "requestId", "value": "", "type": "string" } | ||
| ] | ||
| } |
97 changes: 97 additions & 0 deletions
97
docs/middleware/postman/token-prod.postman_collection.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| { | ||
| "info": { | ||
| "name": "Oullin API — Token Auth (Production)", | ||
| "description": "Postman collection for calling protected endpoints in production via Caddy (https://oullin.io/api). It uses a collection-level pre-request script to compute the required X-API-* headers and signature.", | ||
| "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", | ||
| "_postman_id": "9a1b6e3a-2c24-4e24-8a8c-2f1ca5a7cb21" | ||
| }, | ||
| "item": [ | ||
| { | ||
| "name": "List posts (POST /api/posts)", | ||
| "request": { | ||
| "method": "POST", | ||
| "header": [ | ||
| { "key": "Content-Type", "value": "application/json" } | ||
| ], | ||
| "url": { | ||
| "raw": "{{baseUrl}}/posts", | ||
| "host": ["{{baseUrl}}"], | ||
| "path": ["posts"] | ||
| }, | ||
| "body": { | ||
| "mode": "raw", | ||
| "raw": "{}" | ||
| }, | ||
| "description": "List or filter posts. Requires signed headers generated by the collection pre-request script." | ||
| }, | ||
| "response": [] | ||
| }, | ||
| { | ||
| "name": "Show post (GET /api/posts/hello)", | ||
| "request": { | ||
| "method": "GET", | ||
| "header": [], | ||
| "url": { | ||
| "raw": "{{baseUrl}}/posts/hello", | ||
| "host": ["{{baseUrl}}"], | ||
| "path": ["posts", "hello"] | ||
| }, | ||
| "description": "Fetch a single post by slug (example: hello)." | ||
| }, | ||
| "response": [] | ||
| } | ||
| ], | ||
| "event": [ | ||
| { | ||
| "listen": "prerequest", | ||
| "script": { | ||
| "type": "text/javascript", | ||
| "exec": [ | ||
| "(function() {", | ||
| " // CryptoJS available in Postman sandbox", | ||
| " const crypto = require('crypto-js');", | ||
| " function sha256Hex(str) { return crypto.SHA256(str || '').toString(crypto.enc.Hex); }", | ||
| " function sortedQuery(u) {", | ||
| " const url = new URL(u);", | ||
| " const keys = Array.from(url.searchParams.keys());", | ||
| " keys.sort();", | ||
| " const parts = [];", | ||
| " for (const k of keys) {", | ||
| " const vs = url.searchParams.getAll(k).sort();", | ||
| " for (const v of vs) parts.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));", | ||
| " }", | ||
| " return parts.join('&');", | ||
| " }", | ||
| " const method = pm.request.method.toUpperCase();", | ||
| " const urlStr = pm.environment.get('baseUrl') + pm.request.url.getPathWithQuery();", | ||
| " const urlObj = new URL(urlStr);", | ||
| " const path = urlObj.pathname;", | ||
| " const query = sortedQuery(urlStr);", | ||
| " const username = pm.environment.get('username');", | ||
| " const publicKey = pm.environment.get('publicKey');", | ||
| " const secretKey = pm.environment.get('secretKey');", | ||
| " const timestamp = Math.floor(Date.now() / 1000).toString();", | ||
| " const nonce = crypto.lib.WordArray.random(16).toString();", | ||
| " const body = (method === 'GET' || method === 'DELETE') ? '' : (pm.request.body && pm.request.body.raw || '');", | ||
| " const bodyHash = sha256Hex(body);", | ||
| " const canonical = [method, path, query, username, publicKey, timestamp, nonce, bodyHash].join('\n');", | ||
| " const signature = crypto.HmacSHA256(canonical, secretKey).toString();", | ||
| " pm.request.headers.upsert({ key: 'X-Request-ID', value: pm.environment.get('requestId') || nonce });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Username', value: username });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Key', value: publicKey });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Timestamp', value: timestamp });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Nonce', value: nonce });", | ||
| " pm.request.headers.upsert({ key: 'X-API-Signature', value: signature });", | ||
| "})();" | ||
| ] | ||
| } | ||
| } | ||
| ], | ||
| "variable": [ | ||
| { "key": "baseUrl", "value": "https://oullin.io/api", "type": "string" }, | ||
| { "key": "username", "value": "", "type": "string" }, | ||
| { "key": "publicKey", "value": "", "type": "string" }, | ||
| { "key": "secretKey", "value": "", "type": "string" }, | ||
| { "key": "requestId", "value": "", "type": "string" } | ||
| ] | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.