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
4 changes: 4 additions & 0 deletions api/oas_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,10 @@ class RobotViewSchema:
"type": "string",
"description": "Armored ASCII PGP public key block",
},
"nostr_pubkey": {
"type": "string",
"description": "Nostr public key in hex format",
},
"wants_stealth": {
"type": "boolean",
"default": False,
Expand Down
1 change: 1 addition & 0 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,7 @@ def get(self, request, format=None):
context["encrypted_private_key"] = user.robot.encrypted_private_key
context["earned_rewards"] = user.robot.earned_rewards
context["wants_stealth"] = user.robot.wants_stealth
context["nostr_pubkey"] = user.robot.nostr_pubkey
context["last_login"] = user.last_login

# Adds/generate telegram token and whether it is enabled
Expand Down
3 changes: 3 additions & 0 deletions docs/assets/schemas/api-latest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,9 @@ paths:
public_key:
type: string
description: Armored ASCII PGP public key block
nostr_pubkey:
type: string
description: Nostr public key in hex format
wants_stealth:
type: boolean
default: false
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/models/Robot.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { apiClient } from '../services/api';
import { apiClient, type Auth } from '../services/api';
import type Federation from './Federation.model';
import { type AuthHeaders } from './Slot.model';

class Robot {
constructor(attributes?: Record<any, any>) {
Expand Down Expand Up @@ -31,13 +30,15 @@ class Robot {
Object.assign(this, attributes);
};

getAuthHeaders = (): AuthHeaders | null => {
getAuthHeaders = (): Auth | null => {
const tokenSHA256 = this.tokenSHA256 ?? '';
const encPrivKey = this.encPrivKey ?? '';
const pubKey = this.pubKey ?? '';
const nostrPubkey = this.nostrPubKey ?? '';

return {
tokenSHA256,
nostrPubkey,
keys: {
pubKey: pubKey.split('\n').join('\\'),
encPrivKey: encPrivKey.split('\n').join('\\'),
Expand Down
8 changes: 0 additions & 8 deletions frontend/src/models/Slot.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@ import { roboidentitiesClient } from '../services/Roboidentities/Web';
import { hexToBase91, validateTokenEntropy } from '../utils';
import { getPublicKey } from 'nostr-tools';

export interface AuthHeaders {
tokenSHA256: string;
keys: {
pubKey: string;
encPrivKey: string;
};
}

class Slot {
constructor(
token: string,
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/services/api/ApiNativeClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class ApiNativeClient implements ApiClient {
Authorization: `Token ${auth.tokenSHA256}`,
},
};
} else if (auth?.keys != null) {
} else if (auth?.keys != null && auth.nostrPubkey != null) {
headers = {
...headers,
...{
Authorization: `Token ${auth.tokenSHA256} | Public ${auth.keys.pubKey} | Private ${auth.keys.encPrivKey}`,
Authorization: `Token ${auth.tokenSHA256} | Public ${auth.keys.pubKey} | Private ${auth.keys.encPrivKey} | Nostr ${auth.nostrPubkey}`,
},
};
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/services/api/ApiWebClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ class ApiWebClient implements ApiClient {
Authorization: `Token ${auth.tokenSHA256}`,
},
};
} else if (auth?.keys != null) {
} else if (auth?.keys != null && auth.nostrPubkey != null) {
headers = {
...headers,
...{
Authorization: `Token ${auth.tokenSHA256} | Public ${auth.keys.pubKey} | Private ${auth.keys.encPrivKey}`,
Authorization: `Token ${auth.tokenSHA256} | Public ${auth.keys.pubKey} | Private ${auth.keys.encPrivKey} | Nostr ${auth.nostrPubkey}`,
},
};
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/services/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ApiNativeClient from './ApiNativeClient';

export interface Auth {
tokenSHA256: string;
nostrPubkey?: string;
keys?: { pubKey: string; encPrivKey: string };
}

Expand Down
12 changes: 12 additions & 0 deletions robosats/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@ def process_request(self, request):
split_auth = auth_header.split(" | ")

if len(split_auth) == 3:
# Deprecated in favor of len 4
request.META["HTTP_AUTHORIZATION"] = split_auth[0]
request.META["PUBLIC_KEY"] = split_auth[1]
request.META["ENCRYPTED_PRIVATE_KEY"] = split_auth[2]
elif len(split_auth) == 4:
request.META["HTTP_AUTHORIZATION"] = split_auth[0]
request.META["PUBLIC_KEY"] = split_auth[1]
request.META["ENCRYPTED_PRIVATE_KEY"] = split_auth[2]
request.META["NOSTR_PUBKEY"] = split_auth[3]


class RobotTokenSHA256AuthenticationMiddleWare:
Expand Down Expand Up @@ -108,11 +114,13 @@ def __call__(self, request):
# Authorization header or in the Cookies.
public_key = ""
encrypted_private_key = ""
nostr_pubkey = ""

public_key = request.META.get("PUBLIC_KEY", "").replace("Public ", "")
encrypted_private_key = request.META.get(
"ENCRYPTED_PRIVATE_KEY", ""
).replace("Private ", "")
nostr_pubkey = request.META.get("NOSTR_PUBKEY", "").replace("Nostr ", "")

# Some legacy (pre-federation) clients will still send keys as cookies
if public_key == "" or encrypted_private_key == "":
Expand Down Expand Up @@ -158,6 +166,10 @@ def __call__(self, request):
if not user.robot.encrypted_private_key:
user.robot.encrypted_private_key = encrypted_private_key

# Add nostr key to the new user
if not user.robot.nostr_pubkey:
user.robot.nostr_pubkey = nostr_pubkey

update_last_login(None, user)
user.save()

Expand Down
3 changes: 2 additions & 1 deletion tests/utils/trade.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ def get_robot_auth(self, robot_index, first_encounter=False):
b91_token = read_file(f"tests/robots/{robot_index}/b91_token")
pub_key = read_file(f"tests/robots/{robot_index}/pub_key")
enc_priv_key = read_file(f"tests/robots/{robot_index}/enc_priv_key")
nostr_pubkey = read_file(f"tests/robots/{robot_index}/nostr_pubkey")

# First time a robot authenticated, it is registered by the backend, so pub_key and enc_priv_key is needed
if first_encounter:
headers = {
"HTTP_AUTHORIZATION": f"Token {b91_token} | Public {pub_key} | Private {enc_priv_key}"
"HTTP_AUTHORIZATION": f"Token {b91_token} | Public {pub_key} | Private {enc_priv_key} | Nostr {nostr_pubkey}"
}
else:
headers = {"HTTP_AUTHORIZATION": f"Token {b91_token}"}
Expand Down
Loading