@cocalc/server
Version:
CoCalc server functionality: functions used by either the hub and the next.js server
163 lines (162 loc) • 6.28 kB
TypeScript
import { AuthenticateOptions } from "passport";
import { Router } from "express";
import { PostgreSQL } from "@cocalc/database/postgres/types";
export interface InitPassport {
router: Router;
database: PostgreSQL;
host: string;
cb: (err?: any) => void;
}
interface RecordSignInOpts {
ip_address: string;
successful: boolean;
database: PostgreSQL;
email_address?: string;
account_id?: string;
remember_me: boolean;
}
export interface PassportLoginOpts {
passports: {
[k: string]: PassportStrategyDB;
};
database: PostgreSQL;
strategyName: string;
record_sign_in: (opts: RecordSignInOpts) => void;
profile: any;
id: string;
first_name?: string;
last_name?: string;
full_name?: string;
emails?: string[];
req: any;
res: any;
update_on_login: boolean;
cookie_ttl_s?: number;
host: string;
cb?: (err: any) => void;
}
export interface PassportManagerOpts {
router: Router;
database: PostgreSQL;
host: string;
}
export interface PassportLoginLocals {
account_id: string | undefined;
email_address: string | undefined;
new_account_created: boolean;
has_valid_remember_me: boolean;
target: string;
cookies: any;
remember_me_cookie: string;
get_api_key: string;
action: "regenerate" | "get" | undefined;
api_key: string | undefined;
}
export declare type LoginInfoDerivator<T> = (profile: any) => T;
export interface StrategyConf {
name: string;
type: PassportTypes;
PassportStrategyConstructor: any;
extra_opts?: {
enableProof?: boolean;
profileFields?: string[];
includeEmail?: boolean;
};
auth_opts?: AuthenticateOptions;
login_info: {
id: string | LoginInfoDerivator<string>;
first_name?: string | LoginInfoDerivator<string>;
last_name?: string | LoginInfoDerivator<string>;
full_name?: string | LoginInfoDerivator<string>;
emails?: string | LoginInfoDerivator<string[]>;
};
userinfoURL?: string;
update_on_login?: boolean;
cookie_ttl_s?: number;
}
export declare type LoginInfoKeys = "id" | "first_name" | "last_name" | "emails";
export declare const PassportTypesList: readonly ["email", "activedirectory", "apple", "azuread", "gitlab2", "oauth1", "oauth2", "oauth2next", "oidc", "orcid", "saml"];
export declare type PassportTypes = typeof PassportTypesList[number];
export declare function isOAuth2(type: PassportTypes): boolean;
export declare type PassportLoginInfo = {
[key in LoginInfoKeys]?: string;
};
/**
* To confgure a passport strategy, the "type" field is required.
* It associates these config parameters with a strategy constructor from one of the passport.js strategies.
* The remaining fields, except for type, clientID, clientSecret, and callbackURL, userinfoURL, login_info are passed to that constructor.
* Additionally, there are default values for some of the fields, e.g. for the SAML2.0 strategy.
* Please check the hub/auth.ts file for more details.
* Regarding the userinfoURL, this is used by OAuth2 to get the profile.
* The "login_info" field is a mapping from "cocalc" profile fields, that end up in the DB,
* to the entries in the generated profile object. The DB entry can only be a string and
* processing is done by using the "dot-object" npm library.
* What should be provided is a mapping like that (the default for OAuth2), which in particular provides a unique id (a number or email address):
* {
* id: "id",
* first_name: "name.givenName",
* last_name: "name.familyName",
* emails: "emails[0].value",
* }
*/
export interface PassportStrategyDBConfig {
type: PassportTypes;
clientID?: string;
clientSecret?: string;
authorizationURL?: string;
tokenURL?: string;
userinfoURL?: string;
login_info?: PassportLoginInfo;
auth_opts?: {
[key: string]: string;
};
}
/**
* The "info" column contains information, which is relevant to CoCalc's side of SSO strategies.
* - public (default true): if false, the strategy is not shown prominently, but moved to the dedicated /sso/... pages.
* Set this to false for all "institutional" SSO connections. (public would be Google, Twitter, etc. where anyone can have an account)
* - do_not_hide: if public is false and do_not_hide is true, the strategy is still shown prominently.
* - exclusive_domains: a list of domain extensions, matching also subdomains, e.g. ["example.com", "example.org"]
* would match foo@example.com and bar@baz.example.org
* The ultimate intention is that users with such email addresses have to go through that authentication mechanism.
* They're also prevented from linking with other passports, changing email address, or unlinking that passport from their account.
* That way, the organization behind that SSO mechanism has full control over the user's account.
* - display: The string that's presented to the user as the name of that SSO strategy.
* - description: A longer description of the strategy, could be markdown, shown on the dedicated /sso/... pages.
* - icon: A URL to an icon
* - disabled: if true, this is ignored during the initialization
* - update_on_login: if true, the user's profile is updated on login (first and last name, not email)
* - cookie_ttl_s: how long the remember_me cookied lasts (default is a month or so).
* This could be set to a much shorter period to force users more frequently to re-login.
*/
export interface PassportStrategyDBInfo {
public?: boolean;
do_not_hide?: boolean;
exclusive_domains?: string[];
display?: string;
description?: string;
icon?: string;
disabled?: boolean;
update_on_login?: boolean;
cookie_ttl_s?: number;
}
export interface PassportStrategyDB {
strategy: string;
conf: PassportStrategyDBConfig;
info?: PassportStrategyDBInfo;
}
export interface StrategyInstanceOpts {
type: PassportTypes;
opts: {
[key: string]: any;
};
userinfoURL: string | undefined;
PassportStrategyConstructor: new (options: any, verify: any) => any;
}
export interface UserProfileCallbackOpts {
strategy_instance: any;
userinfoURL: string;
L2: Function;
type: PassportTypes;
}
export {};