Skip to content

Commit

Permalink
Merge pull request #1811 from myConsciousness/refactor-oauth
Browse files Browse the repository at this point in the history
refactor oauth (#1811)
  • Loading branch information
myConsciousness authored Nov 19, 2024
2 parents 814e6b3 + adb3554 commit 6879865
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 30 deletions.
5 changes: 5 additions & 0 deletions packages/atproto/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Release Note

## v0.13.1

- Retry if a DPoP nonce error occurs during the execution of `OAuthClient.refresh`.
- Add `restoreOAuthSession` function.

## v0.13.0

- Expose `atproto_oauth` package.
Expand Down
4 changes: 2 additions & 2 deletions packages/atproto/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: atproto
description: The most famous and powerful Dart/Flutter library for AT Protocol.
version: 0.13.0
version: 0.13.1
homepage: https://atprotodart.com
documentation: https://atprotodart.com/docs/packages/atproto
repository: https://github.com/myConsciousness/atproto.dart/tree/main/packages/atproto
Expand All @@ -17,7 +17,7 @@ topics:
- api

dependencies:
atproto_core: ^0.11.0
atproto_core: ^0.11.1
freezed_annotation: ^2.4.1
json_annotation: ^4.8.1

Expand Down
5 changes: 5 additions & 0 deletions packages/atproto_core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Release Note

## v0.11.1

- Retry if a DPoP nonce error occurs during the execution of `OAuthClient.refresh`.
- Add `restoreOAuthSession` function.

## v0.11.0

- Expose `atproto_oauth` package.
Expand Down
23 changes: 23 additions & 0 deletions packages/atproto_core/lib/src/types/oauth_session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ import 'package:atproto_oauth/atproto_oauth.dart';
import '../utils/jwt.dart';
import '../utils/jwt_decoder.dart';

/// Returns new [OAuthSession] based on parameters.
OAuthSession restoreOAuthSession({
required String accessToken,
required String refreshToken,
String? dPoPNonce,
required String publicKey,
required String privateKey,
}) {
final jwt = decodeJwt(accessToken);

return OAuthSession(
accessToken: accessToken,
refreshToken: refreshToken,
tokenType: 'DPoP',
scope: jwt.scope,
expiresAt: jwt.exp,
sub: jwt.sub,
$dPoPNonce: dPoPNonce ?? '',
$publicKey: publicKey,
$privateKey: privateKey,
);
}

extension OauthSessionExtension on OAuthSession {
/// Returns decoded [accessToken].
Jwt get accessTokenJwt => decodeJwt(accessToken);
Expand Down
4 changes: 2 additions & 2 deletions packages/atproto_core/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: atproto_core
description: Core library for clients and tools. This package is mainly used by https://atprotodart.com packages.
version: 0.11.0
version: 0.11.1
homepage: https://atprotodart.com
documentation: https://atprotodart.com/docs/intro
repository: https://github.com/myConsciousness/atproto.dart/tree/main/packages/atproto_core
Expand All @@ -25,7 +25,7 @@ dependencies:
cbor: ^6.2.0
multiformats: ^0.2.3
universal_io: ^2.2.2
atproto_oauth: ^0.0.1
atproto_oauth: ^0.1.0

dev_dependencies:
lints: ^2.0.1
Expand Down
4 changes: 4 additions & 0 deletions packages/atproto_oauth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release Note

## v0.1.0

- Retry if a DPoP nonce error occurs during the execution of `refresh`.

## v0.0.1

- First Release.
Expand Down
46 changes: 26 additions & 20 deletions packages/atproto_oauth/lib/src/oauth_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ final class OAuthClient {
},
);

final tokenJson = jsonDecode(response.body);
final body = jsonDecode(response.body);

if (response.statusCode == 401 &&
tokenJson['error'] == 'use_dpop_nonce' &&
body['error'] == 'use_dpop_nonce' &&
response.headers.containsKey('dpop-nonce')) {
// Retry with next DPoP nonce
return await this.callback(
Expand All @@ -276,14 +276,13 @@ final class OAuthClient {
}

return OAuthSession(
accessToken: tokenJson['access_token'],
refreshToken: tokenJson['refresh_token'],
tokenType: tokenJson['token_type'],
scope: tokenJson['scope'],
expiresAt: DateTime.now()
.toUtc()
.add(Duration(seconds: tokenJson['expires_in'])),
sub: tokenJson['sub'],
accessToken: body['access_token'],
refreshToken: body['refresh_token'],
tokenType: body['token_type'],
scope: body['scope'],
expiresAt:
DateTime.now().toUtc().add(Duration(seconds: body['expires_in'])),
sub: body['sub'],
$dPoPNonce: response.headers['dpop-nonce']!,
$publicKey: publicKey,
$privateKey: privateKey,
Expand Down Expand Up @@ -356,21 +355,28 @@ final class OAuthClient {
},
);

final body = jsonDecode(response.body);

if (body['error'] == 'use_dpop_nonce' &&
response.headers.containsKey('dpop-nonce')) {
session.$dPoPNonce = response.headers['dpop-nonce']!;

// Retry with next DPoP nonce
return await refresh(session);
}

if (response.statusCode != 200) {
throw OAuthException(response.body);
}

final tokenJson = jsonDecode(response.body);

return OAuthSession(
accessToken: tokenJson['access_token'],
refreshToken: tokenJson['refresh_token'],
tokenType: tokenJson['token_type'],
scope: tokenJson['scope'],
expiresAt: DateTime.now()
.toUtc()
.add(Duration(seconds: tokenJson['expires_in'])),
sub: tokenJson['sub'],
accessToken: body['access_token'],
refreshToken: body['refresh_token'],
tokenType: body['token_type'],
scope: body['scope'],
expiresAt:
DateTime.now().toUtc().add(Duration(seconds: body['expires_in'])),
sub: body['sub'],
$dPoPNonce: response.headers['dpop-nonce']!,
$publicKey: session.$publicKey,
$privateKey: session.$privateKey,
Expand Down
2 changes: 1 addition & 1 deletion packages/atproto_oauth/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: atproto_oauth
description: Provides tools to handle OAuth for AT Protocol and Bluesky Social.
version: 0.0.1
version: 0.1.0
homepage: https://atprotodart.com
repository: https://github.com/myConsciousness/atproto.dart/tree/main/packages/atproto_oauth
issue_tracker: https://github.com/myConsciousness/atproto.dart/issues
Expand Down
5 changes: 5 additions & 0 deletions packages/bluesky/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Release Note

## v0.18.1

- Retry if a DPoP nonce error occurs during the execution of `OAuthClient.refresh`.
- Add `restoreOAuthSession` function.

## v0.18.0

- Expose `atproto_oauth` package.
Expand Down
12 changes: 10 additions & 2 deletions packages/bluesky/example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import 'dart:io';

import 'package:atproto_core/atproto_core.dart';
import 'package:atproto_core/atproto_oauth.dart';
import 'package:bluesky/app_bsky_embed_video.dart';
import 'package:bluesky/atproto.dart';
import 'package:bluesky/core.dart';
import 'package:bluesky/bluesky.dart';
import 'package:bluesky/bluesky_chat.dart';
import 'package:bluesky/moderation.dart';
Expand Down Expand Up @@ -180,8 +180,16 @@ Future<OAuthSession> get _oAuthSession async {
print(session.$publicKey);
print(session.$privateKey);

// You can restore OAuthSession from stored keys
final restoredSession = restoreOAuthSession(
accessToken: session.accessToken,
refreshToken: session.refreshToken,
publicKey: session.$publicKey,
privateKey: session.$privateKey,
);

// If you want to refresh session
// final refreshed = await oauth.refresh(bsky.oAuthSession!);

return session;
return restoredSession;
}
6 changes: 3 additions & 3 deletions packages/bluesky/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: bluesky
description: The most famous and powerful Dart/Flutter library for Bluesky Social.
version: 0.18.0
version: 0.18.1
homepage: https://atprotodart.com
documentation: https://atprotodart.com/docs/packages/bluesky
repository: https://github.com/myConsciousness/atproto.dart/tree/main/packages/bluesky
Expand All @@ -17,8 +17,8 @@ topics:
- api

dependencies:
atproto_core: ^0.11.0
atproto: ^0.13.0
atproto_core: ^0.11.1
atproto: ^0.13.1
freezed_annotation: ^2.4.1
json_annotation: ^4.8.1
characters: ^1.3.0
Expand Down

0 comments on commit 6879865

Please sign in to comment.