Skip to content

Commit

Permalink
[CHAT-1650] Add user, application level token revoke helpers and iat …
Browse files Browse the repository at this point in the history
…claim in tokens (#674)
  • Loading branch information
SiddhantAgarwal authored May 21, 2021
1 parent 8c38f79 commit 3b504e6
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
61 changes: 59 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,59 @@ export class StreamChat<
return await this.patch<APIResponse>(this.baseURL + '/app', options);
}

_normalizeDate = (before: Date | string | null | undefined): string | null => {
if (before === undefined) {
before = new Date().toISOString();
}

if (before instanceof Date) {
before = before.toISOString();
}

if (before === '') {
throw new Error(
"Don't pass blank string for since, use null instead if resetting the token revoke",
);
}

return before;
};

/**
* Revokes all tokens on application level issued before given time
*/
async revokeTokens(before?: Date | string | null) {
return await this.updateAppSettings({
revoke_tokens_issued_before: this._normalizeDate(before),
});
}

/**
* Revokes token for a user issued before given time
*/
async revokeUserToken(userID: string, before?: Date | string | null) {
return await this.revokeUsersToken([userID], before);
}

/**
* Revokes tokens for a list of users issued before given time
*/
async revokeUsersToken(userIDs: string[], before?: Date | string | null) {
before = this._normalizeDate(before);

const users: PartialUserUpdate<UserType>[] = [];
for (const userID of userIDs) {
users.push({
id: userID,
set: <Partial<UserResponse<UserType>>>{
revoke_tokens_issued_before: before,
},
});
}

return await this.partialUpdateUsers(users);
}

/**
* getAppSettings - retrieves application settings
*/
Expand Down Expand Up @@ -797,16 +850,20 @@ export class StreamChat<
*
* @return {string} Returns a token
*/
createToken(userID: string, exp?: number) {
createToken(userID: string, exp?: number, iat?: number) {
if (this.secret == null) {
throw Error(`tokens can only be created server-side using the API Secret`);
}
const extra: { exp?: number } = {};
const extra: { exp?: number; iat?: number } = {};

if (exp) {
extra.exp = exp;
}

if (iat) {
extra.iat = iat;
}

return JWTUserToken(this.secret, userID, extra, {});
}

Expand Down
4 changes: 4 additions & 0 deletions src/signing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export function JWTUserToken(
{ algorithm: 'HS256', noTimestamp: true },
jwtOptions,
);

if (payload.iat) {
opts.noTimestamp = false;
}
return jwt.sign(payload, apiSecret, opts);
}

Expand Down
3 changes: 3 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export type AppSettingsAPIResponse<
apn?: APNConfig;
firebase?: FirebaseConfig;
};
revoke_tokens_issued_before?: string;
sqs_key?: string;
sqs_secret?: string;
sqs_url?: string;
Expand Down Expand Up @@ -721,6 +722,7 @@ export type UserResponse<UserType = UnknownType> = User<UserType> & {
language?: TranslationLanguages | '';
last_active?: string;
online?: boolean;
revoke_tokens_issued_before?: string;
shadow_banned?: boolean;
updated_at?: string;
};
Expand Down Expand Up @@ -1433,6 +1435,7 @@ export type AppSettings = {
push_config?: {
version?: string;
};
revoke_tokens_issued_before?: string | null;
sqs_key?: string;
sqs_secret?: string;
sqs_url?: string;
Expand Down

0 comments on commit 3b504e6

Please sign in to comment.