package tst import ( . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common" TS "git.eugeniocarvalho.dev/eugeniucarvalho/gg/generators/typescript" ) func createAuthClass(p *Project, file *TS.File) { // auth := p.Auth.Oauth2 // scope, _ := json.Marshal(auth.Client.Scope) file.Line().Comment( "Class gerencia autenticacao e autorizacao da api.", ).Export().Class().Id("Auth").Block(TS.Raw(` // public profile = new Subject(); public profile$ = new Subject(); public profile: any; public cookieDomain: string; public grant: any; public onAuthorize$ = new BehaviorSubject(null); public clientParams = { redirect_uri: '', client_id: '', client_secret: '', scope: [], state: '', }; protected oauthURI: string; protected AuthorizeRequest: Subscription; protected authorizeStatus = new EventEmitter(); // constructor(protected api: `).Id(ApiClassName(p)).Raw(`) { constructor(protected api: ApiInterface) { const options = api.apiOptions; this.oauthURI = options.ACCOUNT_URL; this.clientParams = { redirect_uri: options.REDIRECT_URI, client_id: options.CLIENT_ID, client_secret: options.CLIENT_SECRET, scope: options.SCOPES, state: this.state() }; this.cookieDomain = options.COOKIE_DOMAIN; console.log("create auth instance", options); } protected state() { // return [32, 7, 28].map(k => { return Math.random().toString(k).substr(2) }).join('+'); return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } getProfile() { if (this.profile) { return of(this.profile).pipe(take(1)); } return this.api.http .post(`).Raw("`${this.oauthURI}/api/profile`").Raw(`, {}, this.api.options()) .pipe( take(1), map(profile => this.profile = profile), ); } Authorize(): Observable { if (!this.AuthorizeRequest) { this.AuthorizeRequest = this.getAuthCode().pipe( take(1), switchMap(code => { return this.getAccessToken({ code }); }), catchError(err => { console.log('(catch erro grant)', err); switch (err) { case '': return this.getAccessToken({ request_type: 'refreshToken', refresh_token: this.grant.refresh_token }); case '': err = { type: err }; } throw err; }), take(1), ).subscribe( grant => { this.AuthorizeRequest = null; this.setGrant(grant); this.onAuthorize$.next(grant); this.authorizeStatus.next(grant); }, this.authorizeStatus.error ); } return this.authorizeStatus.pipe(take(1)); } Token() { const g = this.grant; if (g) { return `).Raw("`${g.token_type} ${g.access_token}`;").Raw(` } return ''; } Unauthorize() { // ${this.oauthURI}/api/signout window.location.href = `).Raw("this.location('/api/signout').href").Raw(`; } protected getAccessToken(options: any) { if (this.grant) { return of(this.grant); } const params = Object.assign({ request_type: 'accessToken', client_id: this.clientParams.client_id, state: this.clientParams.state }, options); return this.api.http.post(`).Raw("`${this.oauthURI}/oauth2/token`").Raw(`, {}, Object.assign({}, this.api.httpOptions, { params: params }) ); } protected setGrant(grant) { this.grant = grant; // recupera os dados do usuario // setTimeout(() => this.getProfile().subscribe(data => this.profile$.next(data))); } protected location(path = '/oauth2/authorize'): URL { // Solicita autorização par ao servidor de autenticacao caso não exista um token e nem um codigo const url = new URL(`).Raw("`${this.oauthURI}${path}`").Raw(`); Object.keys(this.clientParams).map((k, v) => { url.searchParams.append(k, this.clientParams[k]); }); return url; } protected getAuthCode() { return new Observable(ob => { const oauth2 = document.createElement('iframe'), url = this.location(); oauth2.id = `).Raw("`iframe-${Math.random().toString(36)}`").Raw(`; Object.assign(oauth2.style, { position:'fixed', top:'-10000px', }) url.searchParams.set('redirect_uri', oauth2.id); function listenAccessCode(event) { // Check sender origin to be trusted // if (event.origin !== "http://example.com") return; const { type, code } = event.data; if (type === 'access_code') { // remove o iframe do dom oauth2.remove(); // submete o codigo if (code) { ob.next(code); } else { ob.error(event.data); } window.removeEventListener('message', listenAccessCode, false); } } window.addEventListener('message', listenAccessCode, false); oauth2.src = url.href; document.body.appendChild(oauth2); oauth2.onload = () => { if (!oauth2.contentDocument) { window.postMessage({ type: 'access_code', error: 'unauthorized' }, '*'); } }; }); } `)) } // return new Observable(observer => { // // Verifica se existe um usuario logado // // Quando o usuario não está logado ele é redirecionado para o servidor de autenticacao // if (!(`).Raw(fmt.Sprintf("/\\s%s=([^;]+);?/gm.exec(", p.Auth.AuthTokenID)).Raw("` ${document.cookie}`").Raw(`))) { // window.location.href = this.location('/signin').href; // } // const res = (g, success = true) => { // let f; // if (success) { // observer.next(g); // while (f = this.api.poolReady.shift()){ // f(); // } // } else { // observer.error(g); // } // observer.complete(); // }; // // Se existe um token de authorizacao // if (this.grant) { // this.setGrant(this.grant); // res(this.grant); // return; // } // this.getAuthCode().subscribe( // code => { // const done = (grant) => { // this.setGrant(grant); // res(this.grant); // }; // this.getAccessToken({ // code: code // }).subscribe( // grant => done(grant), // _ => { // // Falha ao recuperar o token ( não existe ou expirou) // this.getAccessToken({ // request_type: 'refreshToken', // refresh_token: this.grant.refresh_token // }).subscribe( // grant => done(grant), // error => res(error, false) // ); // }); // }, // // Não conseguiu obter o codigo de autenticacao // // acao tomada: redirecionar para a tela de login do sistema // error => { // // window.location.href = `).Raw("`${this.oauthURI}/signout`").Raw(`; // } // ); // });