Skip to content

Commit db00661

Browse files
committed
feat(js): return Session class from auth methods
1 parent 3237708 commit db00661

File tree

12 files changed

+182
-103
lines changed

12 files changed

+182
-103
lines changed

Cargo.lock

+15-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/authz/3rd-party-app/src/pubky-auth-widget.js

+9-25
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,19 @@ export class PubkyAuthWidget extends LitElement {
5555

5656
let [url, promise] = this.pubkyClient.authRequest(this.relay || DEFAULT_HTTP_RELAY, this.caps);
5757

58-
promise.then(x => {
59-
console.log({ x })
58+
promise.then(session => {
59+
console.log({ id: session.pubky().z32(), capabilities: session.capabilities() })
60+
alert(`Successfully signed in to ${session.pubky().z32()} with capabilities: ${session.capabilities().join(",")}`)
6061
}).catch(e => {
6162
console.error(e)
6263
})
6364

65+
// let keypair = pubky.Keypair.random();
66+
// const Homeserver = pubky.PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
67+
// this.pubkyClient.signup(keypair, Homeserver).then(() => {
68+
// this.pubkyClient.sendAuthToken(keypair, url)
69+
// })
70+
6471
this.authUrl = url
6572
}
6673

@@ -108,29 +115,6 @@ export class PubkyAuthWidget extends LitElement {
108115
this.open = !this.open
109116
}
110117

111-
async _onCallback(response) {
112-
try {
113-
// Check if the response is ok (status code 200-299)
114-
if (!response.ok) {
115-
throw new Error(`HTTP error! status: ${response.status}`);
116-
}
117-
118-
// Convert the response to an ArrayBuffer
119-
const arrayBuffer = await response.arrayBuffer();
120-
121-
// Create a Uint8Array from the ArrayBuffer
122-
const authToken = new Uint8Array(arrayBuffer);
123-
124-
let publicKey = await this.pubkyClient.thirdPartySignin(authToken, this.secret)
125-
126-
let session = await this.pubkyClient.session(publicKey);
127-
128-
alert(`Succssfully signed in as ${publicKey.z32()}`)
129-
} catch (error) {
130-
console.error('PubkyAuthWidget: Failed to read incoming AuthToken', error);
131-
}
132-
}
133-
134118
async _copyToClipboard() {
135119
try {
136120
await navigator.clipboard.writeText(this.authUrl);

pubky-common/src/session.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ use crate::{auth::AuthToken, capabilities::Capability, timestamp::Timestamp};
1212
// and get more informations from the user-agent.
1313
#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq)]
1414
pub struct Session {
15-
pub version: usize,
16-
pub pubky: PublicKey,
17-
pub created_at: u64,
15+
version: usize,
16+
pubky: PublicKey,
17+
created_at: u64,
1818
/// User specified name, defaults to the user-agent.
19-
pub name: String,
20-
pub user_agent: String,
21-
pub capabilities: Vec<Capability>,
19+
name: String,
20+
user_agent: String,
21+
capabilities: Vec<Capability>,
2222
}
2323

2424
impl Session {
@@ -33,6 +33,16 @@ impl Session {
3333
}
3434
}
3535

36+
// === Getters ===
37+
38+
pub fn pubky(&self) -> &PublicKey {
39+
&self.pubky
40+
}
41+
42+
pub fn capabilities(&self) -> &Vec<Capability> {
43+
&self.capabilities
44+
}
45+
3646
// === Setters ===
3747

3848
pub fn set_user_agent(&mut self, user_agent: String) -> &mut Self {

pubky-homeserver/src/routes/public.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ fn authorize(
148148
.get_session(cookies, public_key)?
149149
.ok_or(Error::with_status(StatusCode::UNAUTHORIZED))?;
150150

151-
if session.pubky == *public_key
152-
&& session.capabilities.iter().any(|cap| {
151+
if session.pubky() == public_key
152+
&& session.capabilities().iter().any(|cap| {
153153
path.starts_with(&cap.scope[1..])
154154
&& cap
155155
.abilities

pubky/pkg/README.md

+28-6
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ let session = await client.signin(keypair)
8484
- keypair: An instance of [Keypair](#keypair).
8585

8686
Returns:
87-
- session: An instance of [Session](#session).
87+
- An instance of [Session](#session).
8888

8989
#### signout
9090
```js
@@ -102,8 +102,7 @@ let session = await sessionPromise;
102102
```
103103

104104
Sign in to a user's Homeserver, without access to their [Keypair](#keypair), nor even [PublicKey](#publickey),
105-
instead request permissions (showing the user pubkyauthUrl), and await a Session
106-
after the user consenting to that request.
105+
instead request permissions (showing the user pubkyauthUrl), and await a Session after the user consenting to that request.
107106

108107
- relay: A URL to an [HTTP relay](https://httprelay.io/features/link/) endpoint.
109108
- capabilities: A list of capabilities required for the app for example `/pub/pubky.app/:rw,/pub/example.com/:r`.
@@ -112,12 +111,21 @@ Returns:
112111
- pubkyauthUrl: A url to show to the user to scan or paste into an Authenticator app holding the user [Keypair](#keypair)
113112
- sessionPromise: A promise that resolves into a [Session](#session) on success.
114113

115-
#### session
114+
#### sendAuthToken
115+
```js
116+
await client.sendAuthToken(keypair, pubkyauthUrl);
117+
```
118+
Consenting to authentication or authorization according to the required capabilities in the `pubkyauthUrl` , and sign and send an auth token to the requester.
119+
120+
- keypair: An instance of [KeyPair](#keypair)
121+
- pubkyauthUrl: A string `pubkyauth://` url
122+
123+
#### session {#session-method}
116124
```js
117125
let session = await client.session(publicKey)
118126
```
119127
- publicKey: An instance of [PublicKey](#publickey).
120-
- Returns: A session object if signed in, or undefined if not.
128+
- Returns: A [Session](#session) object if signed in, or undefined if not.
121129

122130
#### put
123131
```js
@@ -166,7 +174,7 @@ let keypair = Keypair.fromSecretKey(secretKey)
166174
- Returns: A new Keypair.
167175

168176

169-
#### publicKey
177+
#### publicKey {#publickey-method}
170178
```js
171179
let publicKey = keypair.publicKey()
172180
```
@@ -194,6 +202,20 @@ let pubky = publicKey.z32();
194202
```
195203
Returns: The z-base-32 encoded string representation of the PublicKey.
196204

205+
### Session
206+
207+
#### pubky
208+
```js
209+
let pubky = session.pubky();
210+
```
211+
Returns an instance of [PublicKey](#publickey)
212+
213+
#### capabilities
214+
```js
215+
let capabilities = session.capabilities();
216+
```
217+
Returns an array of capabilities, for example `["/pub/pubky.app/:rw"]`
218+
197219
### Helper functions
198220

199221
#### createRecoveryFile

pubky/pkg/test/auth.js

+34-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import test from 'tape'
22

33
import { PubkyClient, Keypair, PublicKey } from '../index.cjs'
44

5+
const Homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
6+
57
test('auth', async (t) => {
68
const client = PubkyClient.testnet();
79

810
const keypair = Keypair.random()
911
const publicKey = keypair.publicKey()
1012

11-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
12-
await client.signup(keypair, homeserver)
13+
await client.signup(keypair, Homeserver)
1314

1415
const session = await client.session(publicKey)
1516
t.ok(session, "signup")
@@ -29,6 +30,34 @@ test('auth', async (t) => {
2930
}
3031
})
3132

32-
// TODO: test end to end
33-
// TODO: test invalid inputs
34-
test.skip("3rd party signin")
33+
test("3rd party signin", async (t) => {
34+
let keypair = Keypair.random();
35+
let pubky = keypair.publicKey().z32();
36+
37+
// Third party app side
38+
let capabilities = "/pub/pubky.app/:rw,/pub/foo.bar/file:r";
39+
let client = PubkyClient.testnet();
40+
let [pubkyauth_url, pubkyauthResponse] = client
41+
.authRequest("https://demo.httprelay.io/link", capabilities);
42+
43+
if (globalThis.document) {
44+
// Skip `sendAuthToken` in browser
45+
// TODO: figure out why does it fail in browser unit tests
46+
// but not in real browser (check pubky-auth-widget.js commented part)
47+
return
48+
}
49+
50+
// Authenticator side
51+
{
52+
let client = PubkyClient.testnet();
53+
54+
await client.signup(keypair, Homeserver);
55+
56+
await client.sendAuthToken(keypair, pubkyauth_url)
57+
}
58+
59+
let session = await pubkyauthResponse;
60+
61+
t.is(session.pubky().z32(), pubky)
62+
t.deepEqual(session.capabilities(), capabilities.split(','))
63+
})

pubky/pkg/test/public.js

+8-14
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import test from 'tape'
22

33
import { PubkyClient, Keypair, PublicKey } from '../index.cjs'
44

5+
const Homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo');
6+
57
test('public: put/get', async (t) => {
68
const client = PubkyClient.testnet();
79

810
const keypair = Keypair.random();
911

10-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo');
11-
await client.signup(keypair, homeserver);
12+
await client.signup(keypair, Homeserver);
1213

1314
const publicKey = keypair.publicKey();
1415

@@ -46,8 +47,7 @@ test("not found", async (t) => {
4647

4748
const keypair = Keypair.random();
4849

49-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo');
50-
await client.signup(keypair, homeserver);
50+
await client.signup(keypair, Homeserver);
5151

5252
const publicKey = keypair.publicKey();
5353

@@ -64,8 +64,7 @@ test("unauthorized", async (t) => {
6464
const keypair = Keypair.random()
6565
const publicKey = keypair.publicKey()
6666

67-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
68-
await client.signup(keypair, homeserver)
67+
await client.signup(keypair, Homeserver)
6968

7069
const session = await client.session(publicKey)
7170
t.ok(session, "signup")
@@ -92,8 +91,7 @@ test("forbidden", async (t) => {
9291
const keypair = Keypair.random()
9392
const publicKey = keypair.publicKey()
9493

95-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
96-
await client.signup(keypair, homeserver)
94+
await client.signup(keypair, Homeserver)
9795

9896
const session = await client.session(publicKey)
9997
t.ok(session, "signup")
@@ -119,8 +117,7 @@ test("list", async (t) => {
119117
const publicKey = keypair.publicKey()
120118
const pubky = publicKey.z32()
121119

122-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
123-
await client.signup(keypair, homeserver)
120+
await client.signup(keypair, Homeserver)
124121

125122

126123

@@ -251,10 +248,7 @@ test('list shallow', async (t) => {
251248
const publicKey = keypair.publicKey()
252249
const pubky = publicKey.z32()
253250

254-
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
255-
await client.signup(keypair, homeserver)
256-
257-
251+
await client.signup(keypair, Homeserver)
258252

259253
let urls = [
260254
`pubky://${pubky}/pub/a.com/a.txt`,

pubky/src/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl PubkyClient {
118118
///
119119
/// The homeserver is a Pkarr domain name, where the TLD is a Pkarr public key
120120
/// for example "pubky.o4dksfbqk85ogzdb5osziw6befigbuxmuxkuxq8434q89uj56uyy"
121-
pub async fn signup(&self, keypair: &Keypair, homeserver: &PublicKey) -> Result<()> {
121+
pub async fn signup(&self, keypair: &Keypair, homeserver: &PublicKey) -> Result<Session> {
122122
self.inner_signup(keypair, homeserver).await
123123
}
124124

0 commit comments

Comments
 (0)