Feature: OIDC & social authentication (#5190)

---------

Co-authored-by: Moritz Pflanzer <moritz@chickadee-engineering.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
Moritz Pflanzer
2024-02-08 17:15:38 +01:00
committed by GitHub
parent b47f301831
commit c508be6ecd
33 changed files with 1197 additions and 190 deletions

View File

@@ -0,0 +1,30 @@
import { TestBed } from '@angular/core/testing'
import {
DjangoMessageLevel,
DjangoMessagesService,
} from './django-messages.service'
const messages = [
{ level: DjangoMessageLevel.ERROR, message: 'Error Message' },
{ level: DjangoMessageLevel.INFO, message: 'Info Message' },
]
describe('DjangoMessagesService', () => {
let service: DjangoMessagesService
beforeEach(() => {
window['DJANGO_MESSAGES'] = messages
TestBed.configureTestingModule({
providers: [DjangoMessagesService],
})
service = TestBed.inject(DjangoMessagesService)
})
it('should retrieve global django messages if present', () => {
expect(service.get()).toEqual(messages)
window['DJANGO_MESSAGES'] = undefined
expect(service.get()).toEqual([])
})
})

View File

@@ -0,0 +1,27 @@
import { Injectable } from '@angular/core'
// see https://docs.djangoproject.com/en/5.0/ref/contrib/messages/#message-tags
export enum DjangoMessageLevel {
DEBUG = 'debug',
INFO = 'info',
SUCCESS = 'success',
WARNING = 'warning',
ERROR = 'error',
}
export interface DjangoMessage {
level: DjangoMessageLevel
message: string
}
@Injectable({
providedIn: 'root',
})
export class DjangoMessagesService {
constructor() {}
get(): DjangoMessage[] {
// These are embedded in the HTML as raw JS, the service is for convenience
return window['DJANGO_MESSAGES'] ?? []
}
}

View File

@@ -51,4 +51,20 @@ describe('ProfileService', () => {
)
expect(req.request.method).toEqual('POST')
})
it('supports disconnecting a social account', () => {
service.disconnectSocialAccount(1).subscribe()
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}profile/disconnect_social_account/`
)
expect(req.request.method).toEqual('POST')
})
it('calls get social account provider endpoint', () => {
service.getSocialAccountProviders().subscribe()
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}profile/social_account_providers/`
)
expect(req.request.method).toEqual('GET')
})
})

View File

@@ -1,7 +1,10 @@
import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
import { PaperlessUserProfile } from '../data/user-profile'
import {
PaperlessUserProfile,
SocialAccountProvider,
} from '../data/user-profile'
import { environment } from 'src/environments/environment'
@Injectable({
@@ -31,4 +34,17 @@ export class ProfileService {
{}
)
}
disconnectSocialAccount(id: number): Observable<number> {
return this.http.post<number>(
`${environment.apiBaseUrl}${this.endpoint}/disconnect_social_account/`,
{ id: id }
)
}
getSocialAccountProviders(): Observable<SocialAccountProvider[]> {
return this.http.get<SocialAccountProvider[]>(
`${environment.apiBaseUrl}${this.endpoint}/social_account_providers/`
)
}
}