Skip to content

Commit

Permalink
add ability to specify auth token duration on login (#183)
Browse files Browse the repository at this point in the history
  • Loading branch information
alecananian authored Nov 26, 2024
1 parent 95ac5b2 commit ecc2568
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .changeset/loud-hornets-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@treasure-dev/tdk-react": patch
"@treasure-dev/tdk-core": patch
---

Added ability to specify auth token duration with `authTokenDurationSec` config
5 changes: 5 additions & 0 deletions .changeset/weak-bananas-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@treasure-dev/auth": patch
---

Fixed auth token expiration time calculation
1 change: 0 additions & 1 deletion apps/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const main = async () => {
kmsKey: env.TREASURE_AUTH_KMS_KEY,
issuer: env.TREASURE_AUTH_ISSUER,
audience: env.TREASURE_AUTH_AUDIENCE,
expirationTimeSeconds: 86_400, // 1 day
}),
thirdwebAuth: createThirdwebAuth({
domain: env.TREASURE_AUTH_ISSUER,
Expand Down
18 changes: 15 additions & 3 deletions apps/api/src/routes/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,17 @@ export const authRoutes =
},
},
async (req, reply) => {
const verifiedPayload = await thirdwebAuth.verifyPayload(req.body);
const {
body: {
payload: unverifiedPayload,
signature,
authTokenDurationSec = 86_400, // 1 day
},
} = req;
const verifiedPayload = await thirdwebAuth.verifyPayload({
payload: unverifiedPayload,
signature,
});
if (!verifiedPayload.valid) {
return reply
.code(400)
Expand Down Expand Up @@ -225,8 +235,10 @@ export const authRoutes =
const [authTokenResult, userSessionsResult] = await Promise.allSettled([
auth.generateJWT<UserContext>(address, {
issuer: payload.domain,
issuedAt: new Date(payload.issued_at),
expiresAt: new Date(payload.expiration_time),
issuedAt: new Date(),
expiresAt: new Date(
new Date().getTime() + authTokenDurationSec * 1000,
),
context: {
id: user.id,
email: profile.email,
Expand Down
7 changes: 7 additions & 0 deletions apps/api/src/schema/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export const readLoginPayloadReplySchema = loginPayloadSchema;
export const loginBodySchema = Type.Object({
payload: loginPayloadSchema,
signature: Type.String(),
authTokenDurationSec: Type.Optional(
Type.Integer({
minimum: 3_600, // 1 minute
maximum: 604_800, // 1 week
default: 86_400, // 1 day
}),
),
});

export const loginReplySchema = Type.Object({
Expand Down
8 changes: 5 additions & 3 deletions packages/auth/src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ export const createAuth = ({
aud: overrides?.audience ?? audience ?? "treasure.lol",
sub: subject,
iat: Math.floor((overrides?.issuedAt ?? new Date()).getTime() / 1000),
exp:
Math.floor((overrides?.expiresAt ?? new Date()).getTime() / 1000) +
expirationTimeSeconds,
exp: Math.floor(
overrides?.expiresAt
? overrides.expiresAt.getTime() / 1000
: new Date().getTime() / 1000 + expirationTimeSeconds,
),
ctx: overrides?.context ?? {},
};
const message = `${JWT_HEADER}.${base64url(JSON.stringify(payload))}`;
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/connect/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,11 @@ export const createTreasureConnectClient = ({
export const authenticateWallet = async ({
wallet,
tdk,
authTokenDurationSec,
}: {
wallet: Wallet;
tdk: TDKAPI;
authTokenDurationSec?: number;
}) => {
const account = wallet.getAccount();
if (!account) {
Expand All @@ -195,7 +197,10 @@ export const authenticateWallet = async ({

// Log in with signed payload
console.debug("[TDK] Logging in with signed payload");
return tdk.auth.logIn(signedPayload);
return tdk.auth.logIn({
...signedPayload,
authTokenDurationSec,
});
};

export const sendEmailVerificationCode = async ({
Expand Down Expand Up @@ -224,6 +229,7 @@ export const logIn = async (params: ConnectWalletConfig & ConnectConfig) => {
client,
chainId = DEFAULT_TDK_CHAIN_ID,
apiUri = DEFAULT_TDK_API_BASE_URI,
authOptions,
sessionOptions,
...connectWalletParams
} = params;
Expand All @@ -244,6 +250,7 @@ export const logIn = async (params: ConnectWalletConfig & ConnectConfig) => {
const { token, user } = await authenticateWallet({
wallet,
tdk,
authTokenDurationSec: authOptions?.authTokenDurationSec,
});

// Set auth token and wallet on TDK so they can be used in future requests
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import type { TDKAPI } from "./api";
export type EcosystemIdString = `ecosystem.${string}`;
export type TreasureConnectClient = ThirdwebClient;

export type AuthOptions = {
authTokenDurationSec?: number;
};

export type SessionOptions = {
backendWallet: string;
approvedTargets: string[];
Expand All @@ -17,6 +21,7 @@ export type SessionOptions = {
export type ConnectConfig = {
apiUri?: string;
chainId?: number;
authOptions?: AuthOptions;
sessionOptions?: SessionOptions;
};

Expand Down
8 changes: 6 additions & 2 deletions packages/react/src/contexts/treasure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ const TreasureProviderInner = ({
clientId,
ecosystemId = DEFAULT_TDK_ECOSYSTEM_ID,
ecosystemPartnerId,
analyticsOptions,
authOptions,
launcherOptions,
sessionOptions,
autoConnectTimeout = 5_000,
onConnect,
launcherOptions,
analyticsOptions,
}: Props) => {
const [isAuthenticating, setIsAuthenticating] = useState(false);
const [user, setUser] = useState<User | undefined>();
Expand Down Expand Up @@ -245,6 +246,9 @@ const TreasureProviderInner = ({
const result = await authenticateWallet({
wallet,
tdk,
authTokenDurationSec:
authOptions?.authTokenDurationSec ??
sessionOptions?.sessionDurationSec,
});
authToken = result.token;
user = result.user;
Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
AddressString,
AppInfo,
AuthOptions,
Contract,
Device,
EcosystemIdString,
Expand Down Expand Up @@ -44,11 +45,12 @@ export type Config = {
clientId: string;
ecosystemId?: EcosystemIdString;
ecosystemPartnerId: string;
analyticsOptions?: AnalyticsOptions;
authOptions?: AuthOptions;
launcherOptions?: LauncherOptions;
sessionOptions?: SessionOptions;
autoConnectTimeout?: number;
onConnect?: (user: User) => void;
launcherOptions?: LauncherOptions;
analyticsOptions?: AnalyticsOptions;
};

export type ContextValues = {
Expand Down

0 comments on commit ecc2568

Please sign in to comment.