Skip to content

Commit

Permalink
client: allow to authenticate with an existing refresh token (#804)
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysu authored Jan 25, 2024
1 parent bb9a8dd commit fea579a
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-seals-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lens-protocol/client": patch
---

**chore**: Relax node version requirements to >18 <21
5 changes: 5 additions & 0 deletions .changeset/honest-buses-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lens-protocol/client": minor
---

**feat**: Added `authentication.authenticateWith` method to allow to authenticate LensClient with an existing refresh token
5 changes: 0 additions & 5 deletions examples/node/scripts/authentication/authenticate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ import { setupWallet } from '../shared/setupWallet';
async function main() {
const client = new LensClient({
environment: development,
headers: {
origin: 'https://lens-scripts.example',
'user-agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
},
});

const wallet = setupWallet();
Expand Down
21 changes: 21 additions & 0 deletions examples/node/scripts/authentication/authenticateWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { LensClient, development } from '@lens-protocol/client';

async function main() {
const client = new LensClient({
environment: development,
});

const token = 'YOUR_VALID_REFRESH_TOKEN_HERE';
await client.authentication.authenticateWith({ refreshToken: token });

console.log(`Is LensClient authenticated? `, await client.authentication.isAuthenticated());

const accessTokenResult = await client.authentication.getAccessToken();
const accessToken = accessTokenResult.unwrap();
const profileId = await client.authentication.getProfileId();

console.log(`Authenticated profileId: `, profileId);
console.log(`Access token: `, accessToken);
}

main();
36 changes: 36 additions & 0 deletions examples/node/scripts/authentication/overwriteOrigin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { LensClient, development } from '@lens-protocol/client';

import { setupWallet } from '../shared/setupWallet';

async function main() {
const client = new LensClient({
environment: development,
headers: {
origin: 'https://lens-scripts.example',
},
});

const wallet = setupWallet();
const address = await wallet.getAddress();

const managedProfiles = await client.wallet.profilesManaged({ for: wallet.address });

if (managedProfiles.items.length === 0) {
throw new Error(`You don't manage any profiles, create one first`);
}

const { id, text } = await client.authentication.generateChallenge({
signedBy: address,
for: managedProfiles.items[0].id,
});

console.log(`Challenge: `, text); // Notice the origin URL in the challenge message

const signature = await wallet.signMessage(text);

await client.authentication.authenticate({ id, signature });

console.log(`Is LensClient authenticated? `, await client.authentication.isAuthenticated());
}

main();
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
"typescript": "5.2.2"
},
"engines": {
"node": "^18.15.0"
"node": ">=18 <21"
},
"prettier": "@lens-protocol/prettier-config",
"babel": {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/LensClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Environment } from './environments';
import {
Explore,
Feed,
Handle,
Invites,
Modules,
Momoka,
Expand All @@ -19,7 +20,6 @@ import {
Transaction,
Wallet,
} from './submodules';
import { Handle } from './submodules/handle';

/**
* LensClient configuration
Expand Down
5 changes: 5 additions & 0 deletions packages/client/src/authentication/Authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export class Authentication implements IAuthentication {
this.credentials = new CredentialsStorage(context.storage, context.environment.name);
}

async authenticateWith({ refreshToken }: { refreshToken: string }): Promise<void> {
const credentials = new Credentials(undefined, refreshToken);
await this.credentials.set(credentials);
}

async generateChallenge(request: ChallengeRequest): Promise<AuthChallengeFragment> {
return this.api.challenge(request);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/client/src/authentication/IAuthentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import type {
* @group LensClient Modules
*/
export interface IAuthentication {
/**
* Authenticate with an existing, valid refresh token.
*/
authenticateWith({ refreshToken }: { refreshToken: string }): Promise<void>;

/**
* Generate a challenge string for the wallet to sign.
*
Expand Down
13 changes: 13 additions & 0 deletions packages/client/src/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ export type {
LastLoggedInProfileRequest,
LinkHandleToProfileRequest,
UnlinkHandleFromProfileRequest,
HandleToAddressRequest,
HidePublicationRequest,
InviteRequest,
LegacyCollectRequest,
LensTransactionStatusRequest,
ModuleMetadataRequest,
MomokaCommentRequest,
MomokaMirrorRequest,
MomokaPostRequest,
Expand Down Expand Up @@ -217,14 +219,22 @@ export type {
FeeFollowModuleRedeemInput,
FollowModuleInput,
FollowModuleRedeemInput,
FraudReasonInput,
IllegalReasonInput,
MultirecipientFeeCollectModuleInput,
NetworkAddressInput,
NftInput,
OpenActionModuleInput,
ProfileFraudReasonInput,
ProfileReportingReasonInput,
ProfileSpamReasonInput,
PublicationStatsInput,
RecipientDataInput,
ReferenceModuleInput,
ReportingReasonInput,
SensitiveReasonInput,
SimpleCollectOpenActionModuleInput,
SpamReasonInput,
UnknownFollowModuleInput,
UnknownFollowModuleRedeemInput,
UnknownOpenActionActRedeemInput,
Expand All @@ -245,6 +255,7 @@ export type {
ChangeProfileManager,
Exact,
Follow,
FollowStatusBulk,
ImageTransform,
InputMaybe,
Maybe,
Expand Down Expand Up @@ -282,11 +293,13 @@ export {
MarketplaceMetadataAttributeDisplayType,
ModuleType,
MomokaValidatorError,
NftCollectionOwnersOrder,
NftContractType,
NotificationType,
OpenActionCategoryType,
OpenActionModuleType,
PoapTokenLayerType,
PopularNftCollectionsOrder,
ProfileActionHistoryType,
ProfileInterestTypes,
ProfileReportingFraudSubreason,
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/submodules/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './explore';
export * from './feed';
export * from './handle';
export * from './invites';
export * from './modules';
export * from './momoka';
Expand Down
4 changes: 3 additions & 1 deletion packages/client/src/submodules/publication/Publication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -879,12 +879,14 @@ export class Publication {
* Predict the next onchain Publication id for a Profile.
*
* @param request - Request object for the method
* @param request.from - ProfileId of the profile to predict the next onchain publication id for
* @returns Publication Id
*/
async predictNextOnChainPublicationId({
from,
}: {
/**
* Profile Id of the profile to predict the next onchain Publication Id for
*/
from: Scalars['ProfileId']['input'];
}): Promise<Scalars['PublicationId']['output']> {
const result = await this.fetchAll({
Expand Down
2 changes: 1 addition & 1 deletion packages/react-web/src/inbox/useEnhanceConversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type UseEnhanceConversationResult = {
/**
* Enhance XMTP conversation with a profile of the conversation's peer
*
* You MUST be authenticated via {@link useLogin} to use this hook.
* You MUST be authenticated via `useLogin` to use this hook.
*
* @example
* ```tsx
Expand Down
2 changes: 1 addition & 1 deletion packages/react-web/src/inbox/useEnhanceConversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type UseEnhanceConversationsResult = Prettify<
* Enhance XMTP conversations with profiles of the conversations' peers,
* if conversation is between two Lens profiles.
*
* You MUST be authenticated via {@link useLogin} to use this hook.
* You MUST be authenticated via `useLogin` to use this hook.
*
* @example
* ```tsx
Expand Down
2 changes: 1 addition & 1 deletion packages/react-web/src/inbox/useStartLensConversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type UseStartLensConversationResult = ReturnType<typeof useStartConversat
/**
* Start a new XMTP conversation between two Lens profiles.
*
* You MUST be authenticated via {@link useLogin} to use this hook.
* You MUST be authenticated via `useLogin` to use this hook.
*
* @example
* ```tsx
Expand Down
4 changes: 2 additions & 2 deletions packages/react-web/src/inbox/useXmtpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ const defaultOptions: InitXmtpClientOptions = {
};

/**
* Initialize XMTP client using the same Signer as the one provided with {@link LensConfig}.
* Initialize XMTP client using the same Signer as the one provided with `LensConfig`.
* Store XMTP user's decryption key in storage to improve UX.
* Be aware that XMTP user's key must be stored safely.
*
* You MUST be authenticated via {@link useLogin} to use this hook.
* You MUST be authenticated via `useLogin` to use this hook.
*
* @example
* ```tsx
Expand Down
5 changes: 4 additions & 1 deletion packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ export {
UserRejectedError,
WalletConnectionError,
} from '@lens-protocol/domain/entities';
export { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions';
export {
BroadcastingError,
BroadcastingErrorReason,
} from '@lens-protocol/domain/use-cases/transactions';
export { NotFoundError } from './NotFoundError';
export {
InsufficientAllowanceError,
Expand Down

0 comments on commit fea579a

Please sign in to comment.