or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mderrors.mdevents.mdindex.mdoidc-client.mdstorage.mduser-management.mduser-tokens.mdutilities.md

user-tokens.mddocs/

0

# User and Token Information

1

2

User profile and token data structures with comprehensive claims support and token lifecycle management for authenticated users.

3

4

## Capabilities

5

6

### User Class

7

8

Represents an authenticated user with profile information and tokens.

9

10

```typescript { .api }

11

/**

12

* Represents an authenticated user with profile and token information

13

*/

14

class User {

15

constructor(args: {

16

id_token?: string;

17

session_state?: string | null;

18

access_token: string;

19

refresh_token?: string;

20

token_type: string;

21

scope?: string;

22

profile: UserProfile;

23

expires_at?: number;

24

userState?: unknown;

25

url_state?: string;

26

});

27

28

/** The raw ID token */

29

readonly id_token?: string;

30

/** Session state for session management */

31

readonly session_state: string | null;

32

/** The access token for API calls */

33

readonly access_token: string;

34

/** The refresh token for token renewal */

35

readonly refresh_token?: string;

36

/** Token type (usually "Bearer") */

37

readonly token_type: string;

38

/** Space-delimited scope values */

39

readonly scope?: string;

40

/** User profile extracted from ID token */

41

readonly profile: UserProfile;

42

/** Timestamp when access token expires */

43

readonly expires_at?: number;

44

/** Custom state data from authentication */

45

readonly state: unknown;

46

/** URL state parameter */

47

readonly url_state?: string;

48

49

/** Seconds until access token expires */

50

readonly expires_in?: number;

51

/** Whether the access token has expired */

52

readonly expired?: boolean;

53

/** Array of individual scope values */

54

readonly scopes: string[];

55

56

/** Serialize user to string for storage */

57

toStorageString(): string;

58

59

/** Create User from storage string */

60

static fromStorageString(storageString: string): User;

61

}

62

```

63

64

### User Profile Structure

65

66

Standard OIDC user profile with optional claims.

67

68

```typescript { .api }

69

/**

70

* User profile information from ID token and userinfo endpoint

71

*/

72

interface UserProfile extends IdTokenClaims {

73

/** Subject identifier - unique user ID */

74

sub: string;

75

76

// Standard profile claims

77

/** Full display name */

78

name?: string;

79

/** Given name (first name) */

80

given_name?: string;

81

/** Family name (last name) */

82

family_name?: string;

83

/** Middle name */

84

middle_name?: string;

85

/** Casual name or alias */

86

nickname?: string;

87

/** Preferred username for display */

88

preferred_username?: string;

89

/** Profile page URL */

90

profile?: string;

91

/** Picture/avatar URL */

92

picture?: string;

93

/** Website URL */

94

website?: string;

95

96

// Contact claims

97

/** Email address */

98

email?: string;

99

/** Whether email is verified */

100

email_verified?: boolean;

101

/** Phone number */

102

phone_number?: string;

103

/** Whether phone number is verified */

104

phone_number_verified?: boolean;

105

106

// Personal information

107

/** Gender */

108

gender?: string;

109

/** Date of birth (YYYY-MM-DD format) */

110

birthdate?: string;

111

/** Time zone */

112

zoneinfo?: string;

113

/** Locale/language preference */

114

locale?: string;

115

/** Last profile update timestamp */

116

updated_at?: number;

117

118

/** Postal address information */

119

address?: OidcAddressClaim;

120

}

121

122

/**

123

* Standard OIDC address claim structure

124

*/

125

interface OidcAddressClaim {

126

/** Full mailing address */

127

formatted?: string;

128

/** Street address */

129

street_address?: string;

130

/** City or locality */

131

locality?: string;

132

/** State, province, prefecture, or region */

133

region?: string;

134

/** ZIP or postal code */

135

postal_code?: string;

136

/** Country name */

137

country?: string;

138

}

139

```

140

141

### ID Token Claims

142

143

JWT claims structure for ID tokens.

144

145

```typescript { .api }

146

/**

147

* Standard ID token claims from JWT

148

*/

149

interface IdTokenClaims extends JwtClaims {

150

/** Subject identifier */

151

sub: string;

152

/** Authentication time */

153

auth_time?: number;

154

/** Authentication Context Class Reference */

155

acr?: string;

156

/** Authentication Methods References */

157

amr?: string[];

158

/** Authorized party */

159

azp?: string;

160

/** Access token hash */

161

at_hash?: string;

162

/** Code hash */

163

c_hash?: string;

164

/** Nonce value */

165

nonce?: string;

166

}

167

168

/**

169

* Base JWT claims structure

170

*/

171

interface JwtClaims {

172

/** Issuer */

173

iss: string;

174

/** Subject */

175

sub: string;

176

/** Audience */

177

aud: string | string[];

178

/** Expiration time */

179

exp: number;

180

/** Issued at time */

181

iat: number;

182

/** Not before time */

183

nbf?: number;

184

/** JWT ID */

185

jti?: string;

186

187

/** Additional custom claims */

188

[key: string]: unknown;

189

}

190

```

191

192

### Standard OIDC Claims

193

194

Complete set of standard OIDC claims.

195

196

```typescript { .api }

197

/**

198

* Standard OIDC claims as defined in the specification

199

*/

200

interface OidcStandardClaims {

201

/** Subject identifier */

202

sub: string;

203

/** Full display name */

204

name?: string;

205

/** Given name */

206

given_name?: string;

207

/** Family name */

208

family_name?: string;

209

/** Middle name */

210

middle_name?: string;

211

/** Nickname */

212

nickname?: string;

213

/** Preferred username */

214

preferred_username?: string;

215

/** Profile page URL */

216

profile?: string;

217

/** Picture URL */

218

picture?: string;

219

/** Website URL */

220

website?: string;

221

/** Email address */

222

email?: string;

223

/** Email verified flag */

224

email_verified?: boolean;

225

/** Gender */

226

gender?: string;

227

/** Date of birth */

228

birthdate?: string;

229

/** Time zone */

230

zoneinfo?: string;

231

/** Locale */

232

locale?: string;

233

/** Phone number */

234

phone_number?: string;

235

/** Phone verified flag */

236

phone_number_verified?: boolean;

237

/** Address */

238

address?: OidcAddressClaim;

239

/** Last update time */

240

updated_at?: number;

241

}

242

```

243

244

## Usage Examples

245

246

### Working with User Information

247

248

```typescript

249

import { UserManager, User } from "oidc-client-ts";

250

251

const userManager = new UserManager({

252

authority: "https://demo.identityserver.io",

253

client_id: "interactive.public",

254

redirect_uri: "http://localhost:3000/callback",

255

response_type: "code",

256

scope: "openid profile email phone address",

257

});

258

259

// Get current user

260

const user = await userManager.getUser();

261

if (user && !user.expired) {

262

console.log("User Information:", {

263

id: user.profile?.sub,

264

name: user.profile?.name,

265

email: user.profile?.email,

266

emailVerified: user.profile?.email_verified,

267

picture: user.profile?.picture,

268

});

269

270

console.log("Token Information:", {

271

accessToken: user.access_token,

272

tokenType: user.token_type,

273

expiresIn: user.expires_in,

274

scopes: user.scopes,

275

hasRefreshToken: !!user.refresh_token,

276

});

277

}

278

```

279

280

### Token Expiration Handling

281

282

```typescript

283

import { UserManager, User } from "oidc-client-ts";

284

285

const userManager = new UserManager({

286

// ... configuration

287

automaticSilentRenew: true,

288

accessTokenExpiringNotificationTimeInSeconds: 60,

289

});

290

291

// Monitor token expiration

292

userManager.events.addAccessTokenExpiring((user: User) => {

293

console.log(`Access token expiring in ${user.expires_in} seconds`);

294

295

// Could show notification to user

296

showTokenExpirationWarning();

297

});

298

299

userManager.events.addAccessTokenExpired(() => {

300

console.log("Access token has expired");

301

302

// Redirect to login or attempt silent renewal

303

handleTokenExpiration();

304

});

305

306

// Check token status

307

function checkTokenStatus(user: User | null) {

308

if (!user) {

309

return "Not authenticated";

310

}

311

312

if (user.expired) {

313

return "Token expired";

314

}

315

316

if (user.expires_in && user.expires_in < 300) { // 5 minutes

317

return "Token expiring soon";

318

}

319

320

return "Token valid";

321

}

322

```

323

324

### Custom Claims Processing

325

326

```typescript

327

import { UserManager } from "oidc-client-ts";

328

329

const userManager = new UserManager({

330

authority: "https://your-provider.com",

331

client_id: "your-client",

332

redirect_uri: "http://localhost:3000/callback",

333

response_type: "code",

334

scope: "openid profile email custom_scope",

335

336

// Load additional user info

337

loadUserInfo: true,

338

339

// Keep custom claims

340

filterProtocolClaims: ["nbf", "jti", "auth_time", "nonce", "acr", "amr", "azp", "at_hash"],

341

342

// Merge strategy for claims

343

mergeClaimsStrategy: { array: "merge" },

344

});

345

346

// Access custom claims

347

const user = await userManager.getUser();

348

if (user?.profile) {

349

// Standard claims

350

const standardInfo = {

351

name: user.profile.name,

352

email: user.profile.email,

353

picture: user.profile.picture,

354

};

355

356

// Custom claims (assuming your provider includes these)

357

const customInfo = {

358

department: (user.profile as any).department,

359

roles: (user.profile as any).roles,

360

permissions: (user.profile as any).permissions,

361

tenant: (user.profile as any).tenant_id,

362

};

363

364

console.log("Standard claims:", standardInfo);

365

console.log("Custom claims:", customInfo);

366

}

367

```

368

369

### Address Information

370

371

```typescript

372

import { User, OidcAddressClaim } from "oidc-client-ts";

373

374

function displayUserAddress(user: User) {

375

const address = user.profile?.address;

376

if (address) {

377

console.log("User Address:");

378

379

if (address.formatted) {

380

console.log("Formatted:", address.formatted);

381

} else {

382

// Build address from components

383

const components = [

384

address.street_address,

385

address.locality,

386

address.region,

387

address.postal_code,

388

address.country,

389

].filter(Boolean);

390

391

console.log("Address:", components.join(", "));

392

}

393

}

394

}

395

396

// Example address claim structure

397

const exampleAddress: OidcAddressClaim = {

398

formatted: "123 Main St\nAnytown, CA 12345\nUSA",

399

street_address: "123 Main St",

400

locality: "Anytown",

401

region: "CA",

402

postal_code: "12345",

403

country: "USA",

404

};

405

```

406

407

### User Storage and Serialization

408

409

```typescript

410

import { User } from "oidc-client-ts";

411

412

// Manual user storage (normally handled by UserManager)

413

function storeUser(user: User) {

414

const userString = user.toStorageString();

415

localStorage.setItem("oidc.user", userString);

416

}

417

418

function loadUser(): User | null {

419

const userString = localStorage.getItem("oidc.user");

420

if (userString) {

421

try {

422

return User.fromStorageString(userString);

423

} catch (error) {

424

console.error("Failed to load user from storage:", error);

425

localStorage.removeItem("oidc.user");

426

return null;

427

}

428

}

429

return null;

430

}

431

432

// Usage

433

const user = await userManager.getUser();

434

if (user) {

435

storeUser(user);

436

}

437

438

const storedUser = loadUser();

439

if (storedUser && !storedUser.expired) {

440

console.log("Loaded user from storage:", storedUser.profile?.name);

441

}

442

```